Release 0.4
This commit is contained in:
commit
597d7ffb6f
78 files changed
+6736
-3062
No files matched your search
+20
@@ -15,3 +15,23 @@ devscripts
|
||||
backend/data/stackpulse.db
|
||||
backend/data/stackpulse.db-shm
|
||||
backend/data/stackpulse.db-wal
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
!.vscode/extensions.json
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
@@ -3,7 +3,7 @@
|
||||
# 📦 StackPulse 
|
||||
|
||||
**StackPulse** ist eine kleine Web-App, die über die Portainer-API deine Docker-Stacks verwaltet und aktualisiert.
|
||||
Aktuell funktionier StackPulse nur mit der Business-Edition von Portainer. Die Communitiy-Edition wird in einem späteren Release implementiert!
|
||||
Aktuell funktioniert StackPulse nur mit der Business-Edition von Portainer. Die Communitiy-Edition wird in einem späteren Release implementiert!
|
||||
Sie besteht aus einem **Backend (Node.js/Express)** und einem **Frontend (React/Tailwind)**.
|
||||
|
||||
Ziel:
|
||||
@@ -27,7 +27,7 @@ Ziel:
|
||||
|
||||
</details>
|
||||
|
||||
<details open>
|
||||
<details>
|
||||
<summary>✅ v0.2 – Release</summary>
|
||||
|
||||
### Backend
|
||||
@@ -47,37 +47,51 @@ Ziel:
|
||||
|
||||
</details>
|
||||
|
||||
<details open>
|
||||
<summary>🟡 v0.3 – In Entwicklung</summary>
|
||||
<details>
|
||||
<summary>✅ v0.3 – Release</summary>
|
||||
|
||||
### Backend
|
||||
- [ ] Automatische Datenbereinigung: Duplikate bei Stack-IDs erkennen & entfernen
|
||||
- [ ] Erweiterung der Logs
|
||||
- [x] Automatische Datenbereinigung: Duplikate bei Stack-IDs erkennen & entfernen
|
||||
- [x] Erweiterung der Logs
|
||||
- [x] API für Filter & Suche (Stacks nach Name/Status abrufen)
|
||||
- [ ] API für Sortierung der Stacks
|
||||
|
||||
### Frontend
|
||||
- [x] Filter: Stacks nach Name oder Status durchsuchen
|
||||
- [ ] Sortierung: Stacks im Frontend sortieren
|
||||
- [ ] Benachrichtigungen im UI: erfolgreicher/fehlgeschlagener Redeploy (Toast + Notification-Center)
|
||||
- [ ] Visualisierung der Datenbereinigung (Konflikt/Auto-Fix Meldungen)
|
||||
- [x] Benachrichtigungen im UI: erfolgreicher/fehlgeschlagener Redeploy (Toast)
|
||||
- [x] Visualisierung der Datenbereinigung (Konflikt/Auto-Fix Meldungen)
|
||||
|
||||
### Features
|
||||
- [ ] Frontend-Filter und Sortierungen für schnellere Navigation bei vielen Stacks
|
||||
- [ ] Echtzeit-Feedback im UI (Notifications)
|
||||
- [ ] Datenkonsistenz sichern: keine doppelten Stack-IDs mehr
|
||||
- [x] Frontend-Filter für schnellere Navigation bei vielen Stacks
|
||||
- [x] Echtzeit-Feedback im UI (Notifications)
|
||||
- [x] Datenkonsistenz sichern: keine doppelten Stack-IDs mehr
|
||||
|
||||
</details>
|
||||
|
||||
<details open>
|
||||
<summary>✅ v0.4 – Release</summary>
|
||||
|
||||
### Backend
|
||||
- keine Änderungen
|
||||
|
||||
### Frontend
|
||||
- [x] GUI komplett überarbeitet
|
||||
- [x] Umstellung auf Material Tailwind
|
||||
- [x] Dashboard von Creative Tim als neues Frontend
|
||||
|
||||
### Features
|
||||
- [x] Neue, übersichtliche Oberfläche im Material Design
|
||||
- [x] leicht erweiterbar durch vorgefertigte Komponenten
|
||||
- [x] kleine Bugfixes
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>🔮 Geplante Features (v0.4+)</summary>
|
||||
<summary>🔮 Geplante Features (v0.5+)</summary>
|
||||
|
||||
- Notifications (z. B. via Webhooks oder Mail)
|
||||
- Authentifizierung & Benutzerverwaltung
|
||||
- Monitoring (Status, CPU/RAM)
|
||||
- Verbesserte UI/UX
|
||||
- Export/Import von Scheduler-Jobs (z. B. JSON)
|
||||
- Health-Checks nach Redeploy (automatisierte Tests, Statusprüfung)
|
||||
- Integration Community Edition
|
||||
|
||||
</details>
|
||||
|
||||
@@ -13,6 +13,8 @@ CREATE TABLE IF NOT EXISTS redeploy_logs (
|
||||
);
|
||||
`;
|
||||
|
||||
|
||||
|
||||
db.exec(createRedeployLogsTable);
|
||||
|
||||
try {
|
||||
@@ -28,4 +30,17 @@ try {
|
||||
|
||||
console.log('✅ redeploy_logs table ready');
|
||||
|
||||
const createSettingsTable = `
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT,
|
||||
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`;
|
||||
|
||||
db.exec(createSettingsTable);
|
||||
|
||||
console.log('✅ settings table ready');
|
||||
|
||||
|
||||
db.close();
|
||||
@@ -1,15 +1,5 @@
|
||||
import { db } from './index.js';
|
||||
|
||||
const CREATE_TABLE_SQL = `
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT,
|
||||
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`;
|
||||
|
||||
db.prepare(CREATE_TABLE_SQL).run();
|
||||
|
||||
const getSettingStmt = db.prepare('SELECT key, value, updated_at FROM settings WHERE key = ?');
|
||||
const setSettingStmt = db.prepare(`
|
||||
INSERT INTO settings (key, value, updated_at)
|
||||
|
||||
@@ -1183,6 +1183,25 @@ app.get('/api/maintenance/portainer-status', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/maintenance/mode', (req, res) => {
|
||||
try {
|
||||
const { active, message } = req.body ?? {};
|
||||
const normalizedMessage = typeof message === 'string' && message.trim() ? message.trim() : null;
|
||||
const nextState = active
|
||||
? activateMaintenanceMode({ message: normalizedMessage })
|
||||
: deactivateMaintenanceMode({ message: normalizedMessage });
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
maintenance: nextState
|
||||
});
|
||||
} catch (err) {
|
||||
const errorMessage = err.response?.data?.error || err.message || 'Fehler beim Aktualisieren des Wartungsmodus';
|
||||
console.error('❌ [Maintenance] Fehler beim Ändern des Wartungsmodus:', errorMessage);
|
||||
res.status(500).json({ error: errorMessage });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/maintenance/config', (req, res) => {
|
||||
const custom = getCustomPortainerScript();
|
||||
const effective = getEffectivePortainerScript();
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.mt-1{margin-top:.25rem}.flex{display:flex}.grid{display:grid}.h-12{height:3rem}.min-h-screen{min-height:100vh}.w-12{width:3rem}.cursor-not-allowed{cursor:not-allowed}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.items-cLine truncated
|
||||
@@ -0,0 +1,90 @@
|
||||
function RR(e,t){for(var r=0;r<t.length;r++){const n=t[r];if(typeof n!="string"&&!Array.isArray(n)){for(const o in n)if(o!=="default"&&!(o in e)){const a=Object.getOwnPropertyDescriptor(n,o);a&&Object.defineProperty(e,o,a.get?a:{enumerable:!0,get:()=>n[o]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))n(o);new MutationObserver(o=>{for(const a of o)if(a.type==="childList")for(const i of a.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&n(i)}).observe(document,{childList:!0,subtree:!0});function r(o){const a={};return o.integrity&&(a.integrity=o.integrity),o.referrerPolicy&&(a.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?a.credentials="include":o.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function n(o){if(o.ep)return;o.ep=!0;const a=r(o);fetch(o.href,a)}})();function xx(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function Ts(e){if(e.__esModule)return e;var t=e.default;if(typeof t=="function"){var r=function n(){return this instanceof n?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};r.prototype=t.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(e).forEach(function(n){var o=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,o.get?o:{enumerable:!0,get:function(){return e[n]}})}),r}var _x={exports:{}},sd={},Tx={exports:{}},lt={};/**
|
||||
* @license React
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var Cs=Symbol.for("react.element"),NR=Symbol.for("react.portal"),jR=Symbol.for("react.fragment"),AR=Symbol.for("react.strict_mode"),MR=Symbol.for("react.profiler"),IR=Symbol.for("react.provider"),DR=Symbol.for("react.context"),LR=Symbol.for("react.forward_ref"),FR=Symbol.for("react.suspense"),VR=Symbol.for("react.memo"),zR=Symbol.for("react.lazy"),Nm=Symbol.iterator;function BR(e){return e===null||typeof e!="object"?null:(e=Nm&&e[Nm]||e["@@iterator"],typeof e=="function"?e:null)}var Cx={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Ox=Object.assign,Sx={};function Vi(e,t,r){this.props=e,this.context=t,this.refs=Sx,this.updater=r||Cx}Vi.prototype.isReactComponent={};Vi.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};Vi.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function Px(){}Px.prototype=Vi.prototype;function Oh(e,t,r){this.props=e,this.context=t,this.refs=Sx,this.updater=r||Cx}var Sh=Oh.prototype=new Px;Sh.constructor=Oh;Ox(Sh,Vi.prototype);Sh.isPureReactComponent=!0;var jm=Array.isArray,kx=Object.prototype.hasOwnProperty,Ph={current:null},Ex={key:!0,ref:!0,__self:!0,__source:!0};function Rx(e,t,r){var n,o={},a=null,i=null;if(t!=null)for(n in t.ref!==void 0&&(i=t.ref),t.key!==void 0&&(a=""+t.key),t)kx.call(t,n)&&!Ex.hasOwnProperty(n)&&(o[n]=t[n]);var c=arguments.length-2;if(c===1)o.children=r;else if(1<c){for(var p=Array(c),g=0;g<c;g++)p[g]=arguments[g+2];o.children=p}if(e&&e.defaultProps)for(n in c=e.defaultProps,c)o[n]===void 0&&(o[n]=c[n]);return{$$typeof:Cs,type:e,key:a,ref:i,props:o,_owner:Ph.current}}function WR(e,t){return{$$typeof:Cs,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}function kh(e){return typeof e=="object"&&e!==null&&e.$$typeof===Cs}function HR(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,function(r){return t[r]})}var Am=/\/+/g;function Uf(e,t){return typeof e=="object"&&e!==null&&e.key!=null?HR(""+e.key):t.toString(36)}function Iu(e,t,r,n,o){var a=typeof e;(a==="undefined"||a==="boolean")&&(e=null);var i=!1;if(e===null)i=!0;else switch(a){case"string":case"number":i=!0;break;case"object":switch(e.$$typeof){case Cs:case NR:i=!0}}if(i)return i=e,o=o(i),e=n===""?"."+Uf(i,0):n,jm(o)?(r="",e!=null&&(r=e.replace(Am,"$&/")+"/"),Iu(o,t,r,"",function(g){return g})):o!=null&&(kh(o)&&(o=WR(o,r+(!o.key||i&&i.key===o.key?"":(""+o.key).replace(Am,"$&/")+"/")+e)),t.push(o)),1;if(i=0,n=n===""?".":n+":",jm(e))for(var c=0;c<e.length;c++){a=e[c];var p=n+Uf(a,c);i+=Iu(a,t,r,p,o)}else if(p=BR(e),typeof p=="function")for(e=p.call(e),c=0;!(a=e.next()).done;)a=a.value,p=n+Uf(a,c++),i+=Iu(a,t,r,p,o);else if(a==="object")throw t=String(e),Error("Objects are not valid as a React child (found: "+(t==="[object Object]"?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return i}function iu(e,t,r){if(e==null)return e;var n=[],o=0;return Iu(e,n,"","",function(a){return t.call(r,a,o++)}),n}function UR(e){if(e._status===-1){var t=e._result;t=t(),t.then(function(r){(e._status===0||e._status===-1)&&(e._status=1,e._result=r)},function(r){(e._status===0||e._status===-1)&&(e._status=2,e._result=r)}),e._status===-1&&(e._status=0,e._result=t)}if(e._status===1)return e._result.default;throw e._result}var yr={current:null},Du={transition:null},$R={ReactCurrentDispatcher:yr,ReactCurrentBatchConfig:Du,ReactCurrentOwner:Ph};lt.Children={map:iu,forEach:function(e,t,r){iu(e,function(){t.apply(this,arguments)},r)},count:function(e){var t=0;return iu(e,function(){t++}),t},toArray:function(e){return iu(e,function(t){return t})||[]},only:function(e){if(!kh(e))throw Error("React.Children.only expected to receive a single React element child.");return e}};lt.Component=Vi;lt.Fragment=jR;lt.Profiler=MR;lt.PureComponent=Oh;lt.StrictMode=AR;lt.Suspense=FR;lt.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=$R;lt.cloneElement=function(e,t,r){if(e==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var n=Ox({},e.props),o=e.key,a=e.ref,i=e._owner;if(t!=null){if(t.ref!==void 0&&(a=t.ref,i=Ph.current),t.key!==void 0&&(o=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(p in t)kx.call(t,p)&&!Ex.hasOwnProperty(p)&&(n[p]=t[p]===void 0&&c!==void 0?c[p]:t[p])}var p=arguments.length-2;if(p===1)n.children=r;else if(1<p){c=Array(p);for(var g=0;g<p;g++)c[g]=arguments[g+2];n.children=c}return{$$typeof:Cs,type:e.type,key:o,ref:a,props:n,_owner:i}};lt.createContext=function(e){return e={$$typeof:DR,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null},e.Provider={$$typeof:IR,_conLine truncated
|
||||
* @license React
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var qR=A,GR=Symbol.for("react.element"),KR=Symbol.for("react.fragment"),YR=Object.prototype.hasOwnProperty,XR=qR.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,QR={key:!0,ref:!0,__self:!0,__source:!0};function Nx(e,t,r){var n,o={},a=null,i=null;r!==void 0&&(a=""+r),t.key!==void 0&&(a=""+t.key),t.ref!==void 0&&(i=t.ref);for(n in t)YR.call(t,n)&&!QR.hasOwnProperty(n)&&(o[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps,t)o[n]===void 0&&(o[n]=t[n]);return{$$typeof:GR,type:e,key:a,ref:i,props:o,_owner:XR.current}}sd.Fragment=KR;sd.jsx=Nx;sd.jsxs=Nx;_x.exports=sd;var I=_x.exports,$p={},jx={exports:{}},Wr={},Ax={exports:{}},Mx={};/**
|
||||
* @license React
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/(function(e){function t(U,B){var H=U.length;U.push(B);e:for(;0<H;){var K=H-1>>>1,Q=U[K];if(0<o(Q,B))U[K]=B,U[H]=Q,H=K;else break e}}function r(U){return U.length===0?null:U[0]}function n(U){if(U.length===0)return null;var B=U[0],H=U.pop();if(H!==B){U[0]=H;e:for(var K=0,Q=U.length,oe=Q>>>1;K<oe;){var ue=2*(K+1)-1,ie=U[ue],ne=ue+1,be=U[ne];if(0>o(ie,H))ne<Q&&0>o(be,ie)?(U[K]=be,U[ne]=H,K=ne):(U[K]=ie,U[ue]=H,K=ue);else if(ne<Q&&0>o(be,H))U[K]=be,U[ne]=H,K=ne;else break e}}return B}function o(U,B){var H=U.sortIndex-B.sortIndex;return H!==0?H:U.id-B.id}if(typeof performance=="object"&&typeof performance.now=="function"){var a=performance;e.unstable_now=function(){return a.now()}}else{var i=Date,c=i.now();e.unstable_now=function(){return i.now()-c}}var p=[],g=[],v=1,_=null,O=3,C=!1,T=!1,x=!1,b=typeof setTimeout=="function"?setTimeout:null,d=typeof clearTimeout=="function"?clearTimeout:null,l=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function u(U){for(var B=r(g);B!==null;){if(B.callback===null)n(g);else if(B.startTime<=U)n(g),B.sortIndex=B.expirationTime,t(p,B);else break;B=r(g)}}function s(U){if(x=!1,u(U),!T)if(r(p)!==null)T=!0,G(h);else{var B=r(g);B!==null&&X(s,B.startTime-U)}}function h(U,B){T=!1,x&&(x=!1,d(E),E=-1),C=!0;var H=O;try{for(u(B),_=r(p);_!==null&&(!(_.expirationTime>B)||U&&!N());){var K=_.callback;if(typeof K=="function"){_.callback=null,O=_.priorityLevel;var Q=K(_.expirationTime<=B);B=e.unstable_now(),typeof Q=="function"?_.callback=Q:_===r(p)&&n(p),u(B)}else n(p);_=r(p)}if(_!==null)var oe=!0;else{var ue=r(g);ue!==null&&X(s,ue.startTime-B),oe=!1}return oe}finally{_=null,O=H,C=!1}}var m=!1,w=null,E=-1,k=5,P=-1;function N(){return!(e.unstable_now()-P<k)}function j(){if(w!==null){var U=e.unstable_now();P=U;var B=!0;try{B=w(!0,U)}finally{B?D():(m=!1,w=null)}}else m=!1}var D;if(typeof l=="function")D=function(){l(j)};else if(typeof MessageChannel<"u"){var F=new MessageChannel,W=F.port2;F.port1.onmessage=j,D=function(){W.postMessage(null)}}else D=function(){b(j,0)};function G(U){w=U,m||(m=!0,D())}function X(U,B){E=b(function(){U(e.unstable_now())},B)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(U){U.callback=null},e.unstable_continueExecution=function(){T||C||(T=!0,G(h))},e.unstable_forceFrameRate=function(U){0>U||125<U?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):k=0<U?Math.floor(1e3/U):5},e.unstable_getCurrentPriorityLevel=function(){return O},e.unstable_getFirstCallbackNode=function(){return r(p)},e.unstable_next=function(U){switch(O){case 1:case 2:case 3:var B=3;break;default:B=O}var H=O;O=B;try{return U()}finally{O=H}},e.unstable_pauseExecution=function(){},e.unstable_requestPaint=function(){},e.unstable_runWithPriority=function(U,B){switch(U){case 1:case 2:case 3:case 4:case 5:break;default:U=3}var H=O;O=U;try{return B()}finally{O=H}},e.unstable_scheduleCallback=function(U,B,H){var K=e.unstable_now();switch(typeof H=="object"&&H!==null?(H=H.delay,H=typeof H=="number"&&0<H?K+H:K):H=K,U){case 1:var Q=-1;break;case 2:Q=250;break;case 5:Q=1073741823;break;case 4:Q=1e4;break;default:Q=5e3}return Q=H+Q,U={id:v++,callback:B,priorityLevel:U,startTime:H,expirationTime:Q,sortIndex:-1},H>K?(U.sortIndex=H,t(g,U),r(p)===null&&U===r(g)&&(x?(d(E),E=-1):x=!0,X(s,H-K))):(U.sortIndex=Q,t(p,U),T||C||(T=!0,G(h))),U},e.unstable_shouldYield=N,e.unstable_wrapCallback=function(U){var B=O;return function(){var H=O;O=B;try{return U.apply(this,arguments)}finally{O=H}}}})(Mx);Ax.exports=Mx;var JR=Ax.exports;/**
|
||||
* @license React
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var Ix=A,zr=JR;function ye(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,r=1;r<arguments.length;r++)t+="&args[]="+encodeURIComponent(arguments[r]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var Dx=new Set,Yl={};function Ra(e,t){Ci(e,t),Ci(e+"Capture",t)}function Ci(e,t){for(Yl[e]=t,e=0;e<t.length;e++)Dx.add(t[e])}var Zn=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),qp=Object.prototype.hasOwnProperty,ZR=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,Mm={},Im={};function eN(e){return qp.call(Im,e)?!0:qp.call(Mm,e)?!1:ZR.test(e)?Im[e]=!0:(Mm[e]=!0,!1)}function tN(e,t,r,n){if(r!==null&&r.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return n?!1:r!==null?!r.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function rN(e,t,r,n){if(t===null||typeof t>"u"||tN(e,t,r,n))return!0;if(n)return!1;if(r!==null)switch(r.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function wr(e,t,r,n,o,a,i){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=n,this.attributeNamespace=o,this.mustUseProperty=r,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=i}var ar={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){ar[e]=new wr(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];ar[t]=new wr(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){ar[e]=new wr(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){ar[e]=new wr(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){ar[e]=new wr(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){ar[e]=new wr(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){ar[e]=new wr(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){ar[e]=new wr(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){ar[e]=new wr(e,5,!1,e.toLowerCase(),null,!1,!1)});var Rh=/[\-:]([a-z])/g;function Nh(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(Rh,Nh);ar[t]=new wr(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(Rh,Nh);ar[t]=new wr(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(Rh,Nh);ar[t]=new wr(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){ar[e]=new wr(e,1,!1,e.toLowerCase(),null,!1,!1)});ar.xlinkHref=new wr("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){ar[e]=new wr(e,1,!1,e.toLowerCase(),null,!0,!0)});function jh(e,t,r,n){var o=ar.hasOwnProperty(t)?ar[t]:null;(o!==null?o.type!==0:n||!(2<t.length)||t[0]!=="o"&&t[0]!==
Line truncated
|
||||
`+$f+e}var qf=!1;function Gf(e,t){if(!e||qf)return"";qf=!0;var r=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(t,[])}catch(g){var n=g}Reflect.construct(e,[],t)}else{try{t.call()}catch(g){n=g}e.call(t.prototype)}else{try{throw Error()}catch(g){n=g}e()}}catch(g){if(g&&n&&typeof g.stack=="string"){for(var o=g.stack.split(`
|
||||
`),a=n.stack.split(`
|
||||
`),i=o.length-1,c=a.length-1;1<=i&&0<=c&&o[i]!==a[c];)c--;for(;1<=i&&0<=c;i--,c--)if(o[i]!==a[c]){if(i!==1||c!==1)do if(i--,c--,0>c||o[i]!==a[c]){var p=`
|
||||
`+o[i].replace(" at new "," at ");return e.displayName&&p.includes("<anonymous>")&&(p=p.replace("<anonymous>",e.displayName)),p}while(1<=i&&0<=c);break}}}finally{qf=!1,Error.prepareStackTrace=r}return(e=e?e.displayName||e.name:"")?Pl(e):""}function nN(e){switch(e.tag){case 5:return Pl(e.type);case 16:return Pl("Lazy");case 13:return Pl("Suspense");case 19:return Pl("SuspenseList");case 0:case 2:case 15:return e=Gf(e.type,!1),e;case 11:return e=Gf(e.type.render,!1),e;case 1:return e=Gf(e.type,!0),e;default:return""}}function Xp(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Za:return"Fragment";case Ja:return"Portal";case Gp:return"Profiler";case Ah:return"StrictMode";case Kp:return"Suspense";case Yp:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Fx:return(e.displayName||"Context")+".Consumer";case Lx:return(e._context.displayName||"Context")+".Provider";case Mh:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case Ih:return t=e.displayName||null,t!==null?t:Xp(e.type)||"Memo";case So:t=e._payload,e=e._init;try{return Xp(e(t))}catch{}}return null}function oN(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Xp(t);case 8:return t===Ah?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function $o(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function zx(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function aN(e){var t=zx(e)?"checked":"value",r=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),n=""+e[t];if(!e.hasOwnProperty(t)&&typeof r<"u"&&typeof r.get=="function"&&typeof r.set=="function"){var o=r.get,a=r.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(i){n=""+i,a.call(this,i)}}),Object.defineProperty(e,t,{enumerable:r.enumerable}),{getValue:function(){return n},setValue:function(i){n=""+i},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function su(e){e._valueTracker||(e._valueTracker=aN(e))}function Bx(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var r=t.getValue(),n="";return e&&(n=zx(e)?e.checked?"true":"false":e.value),e=n,e!==r?(t.setValue(e),!0):!1}function fc(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Qp(e,t){var r=t.checked;return Dt({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:r??e._wrapperState.initialChecked})}function Lm(e,t){var r=t.defaultValue==null?"":t.defaultValue,n=t.checked!=null?t.checked:t.defaultChecked;r=$o(t.value!=null?t.value:r),e._wrapperState={initialChecked:n,initialValue:r,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function Wx(e,t){t=t.checked,t!=null&&jh(e,"checked",t,!1)}function Jp(e,t){Wx(e,t);var r=$o(t.value),n=t.type;if(r!=null)n==="number"?(r===0&&e.value===""||e.value!=r)&&(e.value=""+r):e.value!==""+r&&(e.value=""+r);else if(n==="submit"||n==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?Zp(e,t.type,r):t.hasOwnProperty("defaultValue")&&Zp(e,t.type,$o(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function Fm(e,t,r){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var n=t.type;if(!(n!=="submit"&&n!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,r||t===e.value||(e.value=t),e.defaultValue=t}r=e.name,r!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,r!==""&&(e.name=r)}function Zp(e,t,r){(t!=="number"||fc(e.ownerDocument)!==e)&&(r==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+r&&(e.defaultValue=""+r))}var kl=Array.isArray;function fi(e,t,r,n){if(e=e.options,t){t={};for(var o=0;o<r.length;o++)t["$"+r[o]]=!0;for(r=0;r<e.length;r++)o=t.hasOwnProperty("$"+e[r].value),e[r].selected!==o&&(e[r].selected=o),o&&n&&(e[r].defaultSelected=!0)}else{for(r=""+$o(r),t=null,o=0;o<e.length;o++){if(e[o].value===r){e[o].selected=!0,n&&(e[o].defaultSelected=!0);return}t!==null||e[o].disabled||(t=e[o])}t!==null&&(t.selected=!0)}}function e0(e,t){if(t.dan
Line truncated
|
||||
`).replace(gj,"")}function bu(e,t,r){if(t=ly(t),ly(e)!==t&&r)throw Error(ye(425))}function wc(){}var p0=null,h0=null;function g0(e,t){return e==="textarea"||e==="noscript"||typeof t.children=="string"||typeof t.children=="number"||typeof t.dangerouslySetInnerHTML=="object"&&t.dangerouslySetInnerHTML!==null&&t.dangerouslySetInnerHTML.__html!=null}var b0=typeof setTimeout=="function"?setTimeout:void 0,bj=typeof clearTimeout=="function"?clearTimeout:void 0,sy=typeof Promise=="function"?Promise:void 0,vj=typeof queueMicrotask=="function"?queueMicrotask:typeof sy<"u"?function(e){return sy.resolve(null).then(e).catch(mj)}:b0;function mj(e){setTimeout(function(){throw e})}function ip(e,t){var r=t,n=0;do{var o=r.nextSibling;if(e.removeChild(r),o&&o.nodeType===8)if(r=o.data,r==="/$"){if(n===0){e.removeChild(o),es(t);return}n--}else r!=="$"&&r!=="$?"&&r!=="$!"||n++;r=o}while(r);es(t)}function Lo(e){for(;e!=null;e=e.nextSibling){var t=e.nodeType;if(t===1||t===3)break;if(t===8){if(t=e.data,t==="$"||t==="$!"||t==="$?")break;if(t==="/$")return null}}return e}function uy(e){e=e.previousSibling;for(var t=0;e;){if(e.nodeType===8){var r=e.data;if(r==="$"||r==="$!"||r==="$?"){if(t===0)return e;t--}else r==="/$"&&t++}e=e.previousSibling}return null}var Bi=Math.random().toString(36).slice(2),In="__reactFiber$"+Bi,as="__reactProps$"+Bi,eo="__reactContainer$"+Bi,v0="__reactEvents$"+Bi,yj="__reactListeners$"+Bi,wj="__reactHandles$"+Bi;function fa(e){var t=e[In];if(t)return t;for(var r=e.parentNode;r;){if(t=r[eo]||r[In]){if(r=t.alternate,t.child!==null||r!==null&&r.child!==null)for(e=uy(e);e!==null;){if(r=e[In])return r;e=uy(e)}return t}e=r,r=e.parentNode}return null}function Ps(e){return e=e[In]||e[eo],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function ni(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(ye(33))}function pd(e){return e[as]||null}var m0=[],oi=-1;function Yo(e){return{current:e}}function Tt(e){0>oi||(e.current=m0[oi],m0[oi]=null,oi--)}function yt(e,t){oi++,m0[oi]=e.current,e.current=t}var qo={},hr=Yo(qo),Er=Yo(!1),wa=qo;function Oi(e,t){var r=e.type.contextTypes;if(!r)return qo;var n=e.stateNode;if(n&&n.__reactInternalMemoizedUnmaskedChildContext===t)return n.__reactInternalMemoizedMaskedChildContext;var o={},a;for(a in r)o[a]=t[a];return n&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function Rr(e){return e=e.childContextTypes,e!=null}function xc(){Tt(Er),Tt(hr)}function cy(e,t,r){if(hr.current!==qo)throw Error(ye(168));yt(hr,t),yt(Er,r)}function R_(e,t,r){var n=e.stateNode;if(t=t.childContextTypes,typeof n.getChildContext!="function")return r;n=n.getChildContext();for(var o in n)if(!(o in t))throw Error(ye(108,oN(e)||"Unknown",o));return Dt({},r,n)}function _c(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||qo,wa=hr.current,yt(hr,e),yt(Er,Er.current),!0}function dy(e,t,r){var n=e.stateNode;if(!n)throw Error(ye(169));r?(e=R_(e,t,wa),n.__reactInternalMemoizedMergedChildContext=e,Tt(Er),Tt(hr),yt(hr,e)):Tt(Er),yt(Er,r)}var qn=null,hd=!1,lp=!1;function N_(e){qn===null?qn=[e]:qn.push(e)}function xj(e){hd=!0,N_(e)}function Xo(){if(!lp&&qn!==null){lp=!0;var e=0,t=gt;try{var r=qn;for(gt=1;e<r.length;e++){var n=r[e];do n=n(!0);while(n!==null)}qn=null,hd=!1}catch(o){throw qn!==null&&(qn=qn.slice(e+1)),r_(Lh,Xo),o}finally{gt=t,lp=!1}}return null}var ai=[],ii=0,Tc=null,Cc=0,Jr=[],Zr=0,xa=null,Gn=1,Kn="";function ca(e,t){ai[ii++]=Cc,ai[ii++]=Tc,Tc=e,Cc=t}function j_(e,t,r){Jr[Zr++]=Gn,Jr[Zr++]=Kn,Jr[Zr++]=xa,xa=e;var n=Gn;e=Kn;var o=32-yn(n)-1;n&=~(1<<o),r+=1;var a=32-yn(t)+o;if(30<a){var i=o-o%5;a=(n&(1<<i)-1).toString(32),n>>=i,o-=i,Gn=1<<32-yn(t)+o|r<<o|n,Kn=a+e}else Gn=1<<a|r<<o|n,Kn=e}function qh(e){e.return!==null&&(ca(e,1),j_(e,1,0))}function Gh(e){for(;e===Tc;)Tc=ai[--ii],ai[ii]=null,Cc=ai[--ii],ai[ii]=null;for(;e===xa;)xa=Jr[--Zr],Jr[Zr]=null,Kn=Jr[--Zr],Jr[Zr]=null,Gn=Jr[--Zr],Jr[Zr]=null}var Dr=null,Ir=null,Pt=!1,bn=null;function A_(e,t){var r=tn(5,null,null,0);r.elementType="DELETED",r.stateNode=t,r.return=e,t=e.deletions,t===null?(e.deletions=[r],e.flags|=16):t.push(r)}function fy(e,t){switch(e.tag){case 5:var r=e.type;return t=t.nodeType!==1||r.toLowerCase()!==t.nodeName.toLowerCase()?null:t,t!==null?(e.stateNode=t,Dr=e,Ir=Lo(t.firstChild),!0):!1;case 6:return t=e.pendingProps===""||t.nodeType!==3?null:t,t!==null?(e.stateNode=t,Dr=e,Ir=null,!0):!1;case 13:return t=t.nodeType!==8?null:t,t!==null?(r=xa!==null?{id:Gn,overflow:Kn}:null,e.memoizedState={dehydrated:t,treeContext:r,retryLane:1073741824},r=tn(18,null,null,0),r.stateNode=t,r.return=e,e.child=r,Dr=e,Ir=null,!0):!1;default:return!1}}function y0(e){return(e.mode&1)!==0&&(e.flags&128)===0}function w0(e){if(Pt){var t=Ir;if(t){var r=t;if(!fy(e,t)){if(y0(e))throw Error(ye(418));t=Lo(r.nextSibling);var n=Dr;t&&fy(e,t)?A_(n,r):(e.flags=e.flags&-4097|2,Pt=!1,Dr=e)}}else{if(y0(e))throw Error(ye(418));e.flags=e.flags&-4097|2,Pt=!1,Dr=e}}}function py(e){
Line truncated
|
||||
Error generating stack: `+a.message+`
|
||||
`+a.stack}return{value:e,source:t,stack:o,digest:null}}function fp(e,t,r){return{value:e,source:null,stack:r??null,digest:t??null}}function C0(e,t){try{console.error(t.value)}catch(r){setTimeout(function(){throw r})}}var Rj=typeof WeakMap=="function"?WeakMap:Map;function l5(e,t,r){r=Xn(-1,r),r.tag=3,r.payload={element:null};var n=t.value;return r.callback=function(){jc||(jc=!0,M0=n),C0(e,t)},r}function s5(e,t,r){r=Xn(-1,r),r.tag=3;var n=e.type.getDerivedStateFromError;if(typeof n=="function"){var o=t.value;r.payload=function(){return n(o)},r.callback=function(){C0(e,t)}}var a=e.stateNode;return a!==null&&typeof a.componentDidCatch=="function"&&(r.callback=function(){C0(e,t),typeof n!="function"&&(Vo===null?Vo=new Set([this]):Vo.add(this));var i=t.stack;this.componentDidCatch(t.value,{componentStack:i!==null?i:""})}),r}function xy(e,t,r){var n=e.pingCache;if(n===null){n=e.pingCache=new Rj;var o=new Set;n.set(t,o)}else o=n.get(t),o===void 0&&(o=new Set,n.set(t,o));o.has(r)||(o.add(r),e=Uj.bind(null,e,t,r),t.then(e,e))}function _y(e){do{var t;if((t=e.tag===13)&&(t=e.memoizedState,t=t!==null?t.dehydrated!==null:!0),t)return e;e=e.return}while(e!==null);return null}function Ty(e,t,r,n,o){return e.mode&1?(e.flags|=65536,e.lanes=o,e):(e===t?e.flags|=65536:(e.flags|=128,r.flags|=131072,r.flags&=-52805,r.tag===1&&(r.alternate===null?r.tag=17:(t=Xn(-1,1),t.tag=2,Fo(r,t,1))),r.lanes|=1),e)}var Nj=ao.ReactCurrentOwner,Pr=!1;function vr(e,t,r,n){t.child=e===null?z_(t,null,r,n):Pi(t,e.child,r,n)}function Cy(e,t,r,n,o){r=r.render;var a=t.ref;return bi(t,o),n=og(e,t,r,n,a,o),r=ag(),e!==null&&!Pr?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,ro(e,t,o)):(Pt&&r&&qh(t),t.flags|=1,vr(e,t,n,o),t.child)}function Oy(e,t,r,n,o){if(e===null){var a=r.type;return typeof a=="function"&&!gg(a)&&a.defaultProps===void 0&&r.compare===null&&r.defaultProps===void 0?(t.tag=15,t.type=a,u5(e,t,a,n,o)):(e=qu(r.type,null,n,t,t.mode,o),e.ref=t.ref,e.return=t,t.child=e)}if(a=e.child,!(e.lanes&o)){var i=a.memoizedProps;if(r=r.compare,r=r!==null?r:rs,r(i,n)&&e.ref===t.ref)return ro(e,t,o)}return t.flags|=1,e=Bo(a,n),e.ref=t.ref,e.return=t,t.child=e}function u5(e,t,r,n,o){if(e!==null){var a=e.memoizedProps;if(rs(a,n)&&e.ref===t.ref)if(Pr=!1,t.pendingProps=n=a,(e.lanes&o)!==0)e.flags&131072&&(Pr=!0);else return t.lanes=e.lanes,ro(e,t,o)}return O0(e,t,r,n,o)}function c5(e,t,r){var n=t.pendingProps,o=n.children,a=e!==null?e.memoizedState:null;if(n.mode==="hidden")if(!(t.mode&1))t.memoizedState={baseLanes:0,cachePool:null,transitions:null},yt(ui,Mr),Mr|=r;else{if(!(r&1073741824))return e=a!==null?a.baseLanes|r:r,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,yt(ui,Mr),Mr|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},n=a!==null?a.baseLanes:r,yt(ui,Mr),Mr|=n}else a!==null?(n=a.baseLanes|r,t.memoizedState=null):n=r,yt(ui,Mr),Mr|=n;return vr(e,t,o,r),t.child}function d5(e,t){var r=t.ref;(e===null&&r!==null||e!==null&&e.ref!==r)&&(t.flags|=512,t.flags|=2097152)}function O0(e,t,r,n,o){var a=Rr(r)?wa:hr.current;return a=Oi(t,a),bi(t,o),r=og(e,t,r,n,a,o),n=ag(),e!==null&&!Pr?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,ro(e,t,o)):(Pt&&n&&qh(t),t.flags|=1,vr(e,t,r,o),t.child)}function Sy(e,t,r,n,o){if(Rr(r)){var a=!0;_c(t)}else a=!1;if(bi(t,o),t.stateNode===null)Hu(e,t),F_(t,r,n),T0(t,r,n,o),n=!0;else if(e===null){var i=t.stateNode,c=t.memoizedProps;i.props=c;var p=i.context,g=r.contextType;typeof g=="object"&&g!==null?g=an(g):(g=Rr(r)?wa:hr.current,g=Oi(t,g));var v=r.getDerivedStateFromProps,_=typeof v=="function"||typeof i.getSnapshotBeforeUpdate=="function";_||typeof i.UNSAFE_componentWillReceiveProps!="function"&&typeof i.componentWillReceiveProps!="function"||(c!==n||p!==g)&&vy(t,i,n,g),Po=!1;var O=t.memoizedState;i.state=O,Pc(t,n,i,o),p=t.memoizedState,c!==n||O!==p||Er.current||Po?(typeof v=="function"&&(_0(t,r,v,n),p=t.memoizedState),(c=Po||by(t,r,c,n,O,p,g))?(_||typeof i.UNSAFE_componentWillMount!="function"&&typeof i.componentWillMount!="function"||(typeof i.componentWillMount=="function"&&i.componentWillMount(),typeof i.UNSAFE_componentWillMount=="function"&&i.UNSAFE_componentWillMount()),typeof i.componentDidMount=="function"&&(t.flags|=4194308)):(typeof i.componentDidMount=="function"&&(t.flags|=4194308),t.memoizedProps=n,t.memoizedState=p),i.props=n,i.state=p,i.context=g,n=c):(typeof i.componentDidMount=="function"&&(t.flags|=4194308),n=!1)}else{i=t.stateNode,D_(e,t),c=t.memoizedProps,g=t.type===t.elementType?c:pn(t.type,c),i.props=g,_=t.pendingProps,O=i.context,p=r.contextType,typeof p=="object"&&p!==null?p=an(p):(p=Rr(r)?wa:hr.current,p=Oi(t,p));var C=r.getDerivedStateFromProps;(v=typeof C=="function"||typeof i.getSnapshotBeforeUpdate=="function")||typeof i.UNSAFE_componentWillReceiveProps!="function"&&typeof i.componentWillReceiveProps!="function"||(c!==_||O!==p)&&vy(t,i,n,p),Po=!1,O=t.memoizedState,i.state=O,Pc(t,n,i,o);var T=t.memoizedS
Line truncated
|
||||
* @remix-run/router v1.10.0
|
||||
*
|
||||
* Copyright (c) Remix Software Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE.md file in the root directory of this source tree.
|
||||
*
|
||||
* @license MIT
|
||||
*/function fs(){return fs=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},fs.apply(this,arguments)}var Ao;(function(e){e.Pop="POP",e.Push="PUSH",e.Replace="REPLACE"})(Ao||(Ao={}));const zy="popstate";function tA(e){e===void 0&&(e={});function t(n,o){let{pathname:a,search:i,hash:c}=n.location;return F0("",{pathname:a,search:i,hash:c},o.state&&o.state.usr||null,o.state&&o.state.key||"default")}function r(n,o){return typeof o=="string"?o:Dc(o)}return nA(t,r,null,e)}function It(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function wg(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function rA(){return Math.random().toString(36).substr(2,8)}function By(e,t){return{usr:e.state,key:e.key,idx:t}}function F0(e,t,r,n){return r===void 0&&(r=null),fs({pathname:typeof e=="string"?e:e.pathname,search:"",hash:""},typeof t=="string"?Wi(t):t,{state:r,key:t&&t.key||n||rA()})}function Dc(e){let{pathname:t="/",search:r="",hash:n=""}=e;return r&&r!=="?"&&(t+=r.charAt(0)==="?"?r:"?"+r),n&&n!=="#"&&(t+=n.charAt(0)==="#"?n:"#"+n),t}function Wi(e){let t={};if(e){let r=e.indexOf("#");r>=0&&(t.hash=e.substr(r),e=e.substr(0,r));let n=e.indexOf("?");n>=0&&(t.search=e.substr(n),e=e.substr(0,n)),e&&(t.pathname=e)}return t}function nA(e,t,r,n){n===void 0&&(n={});let{window:o=document.defaultView,v5Compat:a=!1}=n,i=o.history,c=Ao.Pop,p=null,g=v();g==null&&(g=0,i.replaceState(fs({},i.state,{idx:g}),""));function v(){return(i.state||{idx:null}).idx}function _(){c=Ao.Pop;let b=v(),d=b==null?null:b-g;g=b,p&&p({action:c,location:x.location,delta:d})}function O(b,d){c=Ao.Push;let l=F0(x.location,b,d);r&&r(l,b),g=v()+1;let u=By(l,g),s=x.createHref(l);try{i.pushState(u,"",s)}catch(h){if(h instanceof DOMException&&h.name==="DataCloneError")throw h;o.location.assign(s)}a&&p&&p({action:c,location:x.location,delta:1})}function C(b,d){c=Ao.Replace;let l=F0(x.location,b,d);r&&r(l,b),g=v();let u=By(l,g),s=x.createHref(l);i.replaceState(u,"",s),a&&p&&p({action:c,location:x.location,delta:0})}function T(b){let d=o.location.origin!=="null"?o.location.origin:o.location.href,l=typeof b=="string"?b:Dc(b);return It(d,"No window.location.(origin|href) available to create URL for href: "+l),new URL(l,d)}let x={get action(){return c},get location(){return e(o,i)},listen(b){if(p)throw new Error("A history only accepts one active listener");return o.addEventListener(zy,_),p=b,()=>{o.removeEventListener(zy,_),p=null}},createHref(b){return t(o,b)},createURL:T,encodeLocation(b){let d=T(b);return{pathname:d.pathname,search:d.search,hash:d.hash}},push:O,replace:C,go(b){return i.go(b)}};return x}var Wy;(function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"})(Wy||(Wy={}));function oA(e,t,r){r===void 0&&(r="/");let n=typeof t=="string"?Wi(t):t,o=ps(n.pathname||"/",r);if(o==null)return null;let a=I5(e);aA(a);let i=null;for(let c=0;i==null&&c<a.length;++c)i=hA(a[c],bA(o));return i}function I5(e,t,r,n){t===void 0&&(t=[]),r===void 0&&(r=[]),n===void 0&&(n="");let o=(a,i,c)=>{let p={relativePath:c===void 0?a.path||"":c,caseSensitive:a.caseSensitive===!0,childrenIndex:i,route:a};p.relativePath.startsWith("/")&&(It(p.relativePath.startsWith(n),'Absolute route path "'+p.relativePath+'" nested under path '+('"'+n+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),p.relativePath=p.relativePath.slice(n.length));let g=Wo([n,p.relativePath]),v=r.concat(p);a.children&&a.children.length>0&&(It(a.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+g+'".')),I5(a.children,t,v,g)),!(a.path==null&&!a.index)&&t.push({path:g,score:fA(g,a.index),routesMeta:v})};return e.forEach((a,i)=>{var c;if(a.path===""||!((c=a.path)!=null&&c.includes("?")))o(a,i);else for(let p of D5(a.path))o(a,i,p)}),t}function D5(e){let t=e.split("/");if(t.length===0)return[];let[r,...n]=t,o=r.endsWith("?"),a=r.replace(/\?$/,"");if(n.length===0)return o?[a,""]:[a];let i=D5(n.join("/")),c=[];return c.push(...i.map(p=>p===""?a:[a,p].join("/"))),o&&c.push(...i),c.map(p=>e.startsWith("/")&&p===""?"/":p)}function aA(e){e.sort((t,r)=>t.score!==r.score?r.score-t.score:pA(t.routesMeta.map(n=>n.childrenIndex),r.routesMeta.map(n=>n.childrenIndex)))}const iA=/^:\w+$/,lA=3,sA=2,uA=1,cA=10,dA=-2,Hy=e=>e==="*";function fA(e,t){let r=e.split("/"),n=r.length;return r.some(Hy)&&(n+=dA),t&&(n+=sA),r.filter(o=>!Hy(o)).reduce((o,a)=>o+(iA.test(a)?lA:a===""?uA:cA),n)}function pA(e,t){return e.length===t.length&&e.slice(0,-1).every((n,o)=>n===t[o])?e[e.length-1]-t[t.length-1]:0}function hA(e,t){let{routesMeta:r}=e,n={},o="/",a=[];for(let i=0;i<r.length;++i){let c=r[i],p=i===r.length-1,g=o==="/"?t:t.slice(o.length)||"/",v=V0({path:c.relativePath,caseSensitive:c.caseSensitive,end:p},g);if(!v)return null;Object.assign(n,v.paLine truncated
|
||||
* React Router v6.17.0
|
||||
*
|
||||
* Copyright (c) Remix Software Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE.md file in the root directory of this source tree.
|
||||
*
|
||||
* @license MIT
|
||||
*/function Lc(){return Lc=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},Lc.apply(this,arguments)}const Cd=A.createContext(null),F5=A.createContext(null),ja=A.createContext(null),Od=A.createContext(null),Qo=A.createContext({outlet:null,matches:[],isDataRoute:!1}),V5=A.createContext(null);function OA(e,t){let{relative:r}=t===void 0?{}:t;Hi()||It(!1);let{basename:n,navigator:o}=A.useContext(ja),{hash:a,pathname:i,search:c}=Sd(e,{relative:r}),p=i;return n!=="/"&&(p=i==="/"?n:Wo([n,i])),o.createHref({pathname:p,search:c,hash:a})}function Hi(){return A.useContext(Od)!=null}function Aa(){return Hi()||It(!1),A.useContext(Od).location}function z5(e){A.useContext(ja).static||A.useLayoutEffect(e)}function B5(){let{isDataRoute:e}=A.useContext(Qo);return e?FA():SA()}function SA(){Hi()||It(!1);let e=A.useContext(Cd),{basename:t,navigator:r}=A.useContext(ja),{matches:n}=A.useContext(Qo),{pathname:o}=Aa(),a=JSON.stringify(xg(n).map(p=>p.pathnameBase)),i=A.useRef(!1);return z5(()=>{i.current=!0}),A.useCallback(function(p,g){if(g===void 0&&(g={}),!i.current)return;if(typeof p=="number"){r.go(p);return}let v=_g(p,JSON.parse(a),o,g.relative==="path");e==null&&t!=="/"&&(v.pathname=v.pathname==="/"?t:Wo([t,v.pathname])),(g.replace?r.replace:r.push)(v,g.state,g)},[t,r,a,o,e])}function Sd(e,t){let{relative:r}=t===void 0?{}:t,{matches:n}=A.useContext(Qo),{pathname:o}=Aa(),a=JSON.stringify(xg(n).map(i=>i.pathnameBase));return A.useMemo(()=>_g(e,JSON.parse(a),o,r==="path"),[e,a,o,r])}function PA(e,t){return kA(e,t)}function kA(e,t,r){Hi()||It(!1);let{navigator:n}=A.useContext(ja),{matches:o}=A.useContext(Qo),a=o[o.length-1],i=a?a.params:{};a&&a.pathname;let c=a?a.pathnameBase:"/";a&&a.route;let p=Aa(),g;if(t){var v;let x=typeof t=="string"?Wi(t):t;c==="/"||(v=x.pathname)!=null&&v.startsWith(c)||It(!1),g=x}else g=p;let _=g.pathname||"/",O=c==="/"?_:_.slice(c.length)||"/",C=oA(e,{pathname:O}),T=AA(C&&C.map(x=>Object.assign({},x,{params:Object.assign({},i,x.params),pathname:Wo([c,n.encodeLocation?n.encodeLocation(x.pathname).pathname:x.pathname]),pathnameBase:x.pathnameBase==="/"?c:Wo([c,n.encodeLocation?n.encodeLocation(x.pathnameBase).pathname:x.pathnameBase])})),o,r);return t&&T?A.createElement(Od.Provider,{value:{location:Lc({pathname:"/",search:"",hash:"",state:null,key:"default"},g),navigationType:Ao.Pop}},T):T}function EA(){let e=LA(),t=TA(e)?e.status+" "+e.statusText:e instanceof Error?e.message:JSON.stringify(e),r=e instanceof Error?e.stack:null,o={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"},a=null;return A.createElement(A.Fragment,null,A.createElement("h2",null,"Unexpected Application Error!"),A.createElement("h3",{style:{fontStyle:"italic"}},t),r?A.createElement("pre",{style:o},r):null,a)}const RA=A.createElement(EA,null);class NA extends A.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,r){return r.location!==t.location||r.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error||r.error,location:r.location,revalidation:t.revalidation||r.revalidation}}componentDidCatch(t,r){console.error("React Router caught the following error during render",t,r)}render(){return this.state.error?A.createElement(Qo.Provider,{value:this.props.routeContext},A.createElement(V5.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function jA(e){let{routeContext:t,match:r,children:n}=e,o=A.useContext(Cd);return o&&o.static&&o.staticContext&&(r.route.errorElement||r.route.ErrorBoundary)&&(o.staticContext._deepestRenderedBoundaryId=r.route.id),A.createElement(Qo.Provider,{value:t},n)}function AA(e,t,r){var n;if(t===void 0&&(t=[]),r===void 0&&(r=null),e==null){var o;if((o=r)!=null&&o.errors)e=r.matches;else return null}let a=e,i=(n=r)==null?void 0:n.errors;if(i!=null){let c=a.findIndex(p=>p.route.id&&(i==null?void 0:i[p.route.id]));c>=0||It(!1),a=a.slice(0,Math.min(a.length,c+1))}return a.reduceRight((c,p,g)=>{let v=p.route.id?i==null?void 0:i[p.route.id]:null,_=null;r&&(_=p.route.errorElement||RA);let O=t.concat(a.slice(0,g+1)),C=()=>{let T;return v?T=_:p.route.Component?T=A.createElement(p.route.Component,null):p.route.element?T=p.route.element:T=c,A.createElement(jA,{match:p,routeContext:{outlet:c,matches:O,isDataRoute:r!=null},children:T})};return r&&(p.route.ErrorBoundary||p.route.errorElement||g===0)?A.createElement(NA,{location:r.location,revalidation:r.revalidation,component:_,error:v,children:C(),routeContext:{outlet:null,matches:O,isDataRoute:!0}}):C()},null)}var W5=function(e){return e.UseBlocker="useBlocker",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e}(W5||{}),Fc=function(e){return e.UseBlocker="useBlocker",e.UseLoadeLine truncated
|
||||
* React Router DOM v6.17.0
|
||||
*
|
||||
* Copyright (c) Remix Software Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE.md file in the root directory of this source tree.
|
||||
*
|
||||
* @license MIT
|
||||
*/function Vc(){return Vc=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},Vc.apply(this,arguments)}function U5(e,t){if(e==null)return{};var r={},n=Object.keys(e),o,a;for(a=0;a<n.length;a++)o=n[a],!(t.indexOf(o)>=0)&&(r[o]=e[o]);return r}function BA(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function WA(e,t){return e.button===0&&(!t||t==="_self")&&!BA(e)}const HA=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","unstable_viewTransition"],UA=["aria-current","caseSensitive","className","end","style","to","unstable_viewTransition","children"],$A=A.createContext({isTransitioning:!1}),qA="startTransition",Uy=Eh[qA];function GA(e){let{basename:t,children:r,future:n,window:o}=e,a=A.useRef();a.current==null&&(a.current=tA({window:o,v5Compat:!0}));let i=a.current,[c,p]=A.useState({action:i.action,location:i.location}),{v7_startTransition:g}=n||{},v=A.useCallback(_=>{g&&Uy?Uy(()=>p(_)):p(_)},[p,g]);return A.useLayoutEffect(()=>i.listen(v),[i,v]),A.createElement(zA,{basename:t,children:r,location:c.location,navigationType:c.action,navigator:i})}const KA=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",YA=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,$5=A.forwardRef(function(t,r){let{onClick:n,relative:o,reloadDocument:a,replace:i,state:c,target:p,to:g,preventScrollReset:v,unstable_viewTransition:_}=t,O=U5(t,HA),{basename:C}=A.useContext(ja),T,x=!1;if(typeof g=="string"&&YA.test(g)&&(T=g,KA))try{let u=new URL(window.location.href),s=g.startsWith("//")?new URL(u.protocol+g):new URL(g),h=ps(s.pathname,C);s.origin===u.origin&&h!=null?g=h+s.search+s.hash:x=!0}catch{}let b=OA(g,{relative:o}),d=JA(g,{replace:i,state:c,target:p,preventScrollReset:v,relative:o,unstable_viewTransition:_});function l(u){n&&n(u),u.defaultPrevented||d(u)}return A.createElement("a",Vc({},O,{href:T||b,onClick:x||a?n:l,ref:r,target:p}))}),XA=A.forwardRef(function(t,r){let{"aria-current":n="page",caseSensitive:o=!1,className:a="",end:i=!1,style:c,to:p,unstable_viewTransition:g,children:v}=t,_=U5(t,UA),O=Sd(p,{relative:_.relative}),C=Aa(),T=A.useContext(F5),{navigator:x}=A.useContext(ja),b=T!=null&&ZA(O)&&g===!0,d=x.encodeLocation?x.encodeLocation(O).pathname:O.pathname,l=C.pathname,u=T&&T.navigation&&T.navigation.location?T.navigation.location.pathname:null;o||(l=l.toLowerCase(),u=u?u.toLowerCase():null,d=d.toLowerCase());let s=l===d||!i&&l.startsWith(d)&&l.charAt(d.length)==="/",h=u!=null&&(u===d||!i&&u.startsWith(d)&&u.charAt(d.length)==="/"),m={isActive:s,isPending:h,isTransitioning:b},w=s?n:void 0,E;typeof a=="function"?E=a(m):E=[a,s?"active":null,h?"pending":null,b?"transitioning":null].filter(Boolean).join(" ");let k=typeof c=="function"?c(m):c;return A.createElement($5,Vc({},_,{"aria-current":w,className:E,ref:r,style:k,to:p,unstable_viewTransition:g}),typeof v=="function"?v(m):v)});var B0;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(B0||(B0={}));var $y;(function(e){e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})($y||($y={}));function QA(e){let t=A.useContext(Cd);return t||It(!1),t}function JA(e,t){let{target:r,replace:n,state:o,preventScrollReset:a,relative:i,unstable_viewTransition:c}=t===void 0?{}:t,p=B5(),g=Aa(),v=Sd(e,{relative:i});return A.useCallback(_=>{if(WA(_,r)){_.preventDefault();let O=n!==void 0?n:Dc(g)===Dc(v);p(e,{replace:O,state:o,preventScrollReset:a,relative:i,unstable_viewTransition:c})}},[g,p,v,n,o,r,e,a,i,c])}function ZA(e,t){t===void 0&&(t={});let r=A.useContext($A);r==null&&It(!1);let{basename:n}=QA(B0.useViewTransitionState),o=Sd(e,{relative:t.relative});if(!r.isTransitioning)return!1;let a=ps(r.currentLocation.pathname,n)||r.currentLocation.pathname,i=ps(r.nextLocation.pathname,n)||r.nextLocation.pathname;return V0(o.pathname,i)!=null||V0(o.pathname,a)!=null}function eM({title:e,titleId:t,...r},n){return A.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",ref:n,"aria-labelledby":t},r),e?A.createElement("title",{id:t},e):null,A.createElement("path",{fillRule:"evenodd",d:"M3 6.75A.75.75 0 013.75 6h16.5a.75.75 0 010 1.5H3.75A.75.75 0 013 6.75zM3 12a.75.75 0 01.75-.75h16.5a.75.75 0 010 1.5H3.75A.75.75 0 013 12zm0 5.25a.75.75 0 01.75-.75h16.5a.75.75 0 010 1.5H3.75a.75.75 0 01-.75-.75z",clipRule:"evenodd"}))}const tM=A.forwardRef(eM),rM=tM;function nM({title:e,titleId:t,...r},n){return A.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",ref:n,"aria-labelledby":t},r),e?A.createElement("title",{id:t},e):null,A.createElement("path",{fillRule:"evenodd",d:"M5.25 9a6.75 6.75 0 0113.Line truncated
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/(function(e){(function(){var t={}.hasOwnProperty;function r(){for(var n=[],o=0;o<arguments.length;o++){var a=arguments[o];if(a){var i=typeof a;if(i==="string"||i==="number")n.push(a);else if(Array.isArray(a)){if(a.length){var c=r.apply(null,a);c&&n.push(c)}}else if(i==="object"){if(a.toString!==Object.prototype.toString&&!a.toString.toString().includes("[native code]")){n.push(a.toString());continue}for(var p in a)t.call(a,p)&&a[p]&&n.push(p)}}}return n.join(" ")}e.exports?(r.default=r,e.exports=r):window.classNames=r})()})(K5);var $e=K5.exports,Y5={exports:{}},fn={};function Cg(){for(var e,t,r=0,n="";r<arguments.length;)(e=arguments[r++])&&(t=X5(e))&&(n&&(n+=" "),n+=t);return n}function X5(e){if(typeof e=="string")return e;for(var t,r="",n=0;n<e.length;n++)e[n]&&(t=X5(e[n]))&&(r&&(r+=" "),r+=t);return r}function W0(){return W0=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},W0.apply(this,arguments)}function PM(e){var t=function(r){var n=r.theme,o=r.prefix,a={nextPart:new Map,validators:[]};return function(i,c){return c?i.map(function(p){return[p[0],p[1].map(function(g){return typeof g=="string"?c+g:typeof g=="object"?Object.fromEntries(Object.entries(g).map(function(v){return[c+v[0],v[1]]})):g})]}):i}(Object.entries(r.classGroups),o).forEach(function(i){H0(i[1],a,i[0],n)}),a}(e);return{getClassGroupId:function(r){var n=r.split("-");return n[0]===""&&n.length!==1&&n.shift(),Q5(n,t)||function(o){if(Gy.test(o)){var a=Gy.exec(o)[1],i=a==null?void 0:a.substring(0,a.indexOf(":"));if(i)return"arbitrary.."+i}}(r)},getConflictingClassGroupIds:function(r){return e.conflictingClassGroups[r]||[]}}}function Q5(e,t){var r;if(e.length===0)return t.classGroupId;var n=t.nextPart.get(e[0]),o=n?Q5(e.slice(1),n):void 0;if(o)return o;if(t.validators.length!==0){var a=e.join("-");return(r=t.validators.find(function(i){return(0,i.validator)(a)}))==null?void 0:r.classGroupId}}Object.defineProperty(fn,"__esModule",{value:!0});var Gy=/^\[(.+)\]$/;function H0(e,t,r,n){e.forEach(function(o){if(typeof o!="string"){if(typeof o=="function")return o.isThemeGetter?void H0(o(n),t,r,n):void t.validators.push({validator:o,classGroupId:r});Object.entries(o).forEach(function(a){H0(a[1],Ky(t,a[0]),r,n)})}else(o===""?t:Ky(t,o)).classGroupId=r})}function Ky(e,t){var r=e;return t.split("-").forEach(function(n){r.nextPart.has(n)||r.nextPart.set(n,{nextPart:new Map,validators:[]}),r=r.nextPart.get(n)}),r}function kM(e){if(e<1)return{get:function(){},set:function(){}};var t=0,r=new Map,n=new Map;function o(a,i){r.set(a,i),++t>e&&(t=0,n=r,r=new Map)}return{get:function(a){var i=r.get(a);return i!==void 0?i:(i=n.get(a))!==void 0?(o(a,i),i):void 0},set:function(a,i){r.has(a)?r.set(a,i):o(a,i)}}}function EM(e){var t=e.separator||":";return function(r){for(var n=0,o=[],a=0,i=0;i<r.length;i++){var c=r[i];n===0&&c===t[0]&&(t.length!==1&&r.slice(i,i+t.length)!==t||(o.push(r.slice(a,i)),a=i+t.length)),c==="["?n++:c==="]"&&n--}var p=o.length===0?r:r.substring(a),g=p.startsWith("!");return{modifiers:o,hasImportantModifier:g,baseClassName:g?p.substring(1):p}}}function RM(e){return W0({cache:kM(e.cacheSize),splitModifiers:EM(e)},PM(e))}var NM=/\s+/;function jM(e,t){var r=t.splitModifiers,n=t.getClassGroupId,o=t.getConflictingClassGroupIds,a=new Set;return e.trim().split(NM).map(function(i){var c=r(i),p=c.modifiers,g=c.hasImportantModifier,v=n(c.baseClassName);if(!v)return{isTailwindClass:!1,originalClassName:i};var _=function(O){if(O.length<=1)return O;var C=[],T=[];return O.forEach(function(x){x[0]==="["?(C.push.apply(C,T.sort().concat([x])),T=[]):T.push(x)}),C.push.apply(C,T.sort()),C}(p).join(":");return{isTailwindClass:!0,modifierId:g?_+"!":_,classGroupId:v,originalClassName:i}}).reverse().filter(function(i){if(!i.isTailwindClass)return!0;var c=i.modifierId,p=i.classGroupId,g=c+p;return!a.has(g)&&(a.add(g),o(p).forEach(function(v){return a.add(c+v)}),!0)}).reverse().map(function(i){return i.originalClassName}).join(" ")}function U0(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];var n,o,a,i=c;function c(g){var v=t[0],_=t.slice(1).reduce(function(O,C){return C(O)},v());return n=RM(_),o=n.cache.get,a=n.cache.set,i=p,p(g)}function p(g){var v=o(g);if(v)return v;var _=jM(g,n);return a(g,_),_}return function(){return i(Cg.apply(null,arguments))}}function _t(e){var t=function(r){return r[e]||[]};return t.isThemeGetter=!0,t}var Jo=/^\[(.+)\]$/,AM=/^\d+\/\d+$/,MM=new Set(["px","full","screen"]),IM=/^(\d+)?(xs|sm|md|lg|xl)$/,DM=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh)/,LM=/^-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/;function Xr(e){return!Number.isNaN(Number(e))||MM.has(e)||AM.test(e)||ko(e)}function ko(e){var t,r=(t=Jo.exec(e))==null?void 0:t[1];return!!r&&(r.startsWith("length:")||DM.test(r))}function J5(e){var t,r=(t=Jo.exec(e))==null?void 0:t[1];return!!r&&r.startsWLine truncated
|
||||
* tabbable 6.2.0
|
||||
* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
|
||||
*/var PL=["input:not([inert])","select:not([inert])","textarea:not([inert])","a[href]:not([inert])","button:not([inert])","[tabindex]:not(slot):not([inert])","audio[controls]:not([inert])","video[controls]:not([inert])",'[contenteditable]:not([contenteditable="false"]):not([inert])',"details>summary:first-of-type:not([inert])","details:not([inert])"],ah=PL.join(","),aS=typeof Element>"u",ys=aS?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,Yc=!aS&&Element.prototype.getRootNode?function(e){var t;return e==null||(t=e.getRootNode)===null||t===void 0?void 0:t.call(e)}:function(e){return e==null?void 0:e.ownerDocument},Xc=function e(t,r){var n;r===void 0&&(r=!0);var o=t==null||(n=t.getAttribute)===null||n===void 0?void 0:n.call(t,"inert"),a=o===""||o==="true",i=a||r&&t&&e(t.parentNode);return i},kL=function(t){var r,n=t==null||(r=t.getAttribute)===null||r===void 0?void 0:r.call(t,"contenteditable");return n===""||n==="true"},EL=function(t,r,n){if(Xc(t))return[];var o=Array.prototype.slice.apply(t.querySelectorAll(ah));return r&&ys.call(t,ah)&&o.unshift(t),o=o.filter(n),o},RL=function e(t,r,n){for(var o=[],a=Array.from(t);a.length;){var i=a.shift();if(!Xc(i,!1))if(i.tagName==="SLOT"){var c=i.assignedElements(),p=c.length?c:i.children,g=e(p,!0,n);n.flatten?o.push.apply(o,g):o.push({scopeParent:i,candidates:g})}else{var v=ys.call(i,ah);v&&n.filter(i)&&(r||!t.includes(i))&&o.push(i);var _=i.shadowRoot||typeof n.getShadowRoot=="function"&&n.getShadowRoot(i),O=!Xc(_,!1)&&(!n.shadowRootFilter||n.shadowRootFilter(i));if(_&&O){var C=e(_===!0?i.children:_.children,!0,n);n.flatten?o.push.apply(o,C):o.push({scopeParent:i,candidates:C})}else a.unshift.apply(a,i.children)}}return o},iS=function(t){return!isNaN(parseInt(t.getAttribute("tabindex"),10))},lS=function(t){if(!t)throw new Error("No node provided");return t.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(t.tagName)||kL(t))&&!iS(t)?0:t.tabIndex},NL=function(t,r){var n=lS(t);return n<0&&r&&!iS(t)?0:n},jL=function(t,r){return t.tabIndex===r.tabIndex?t.documentOrder-r.documentOrder:t.tabIndex-r.tabIndex},sS=function(t){return t.tagName==="INPUT"},AL=function(t){return sS(t)&&t.type==="hidden"},ML=function(t){var r=t.tagName==="DETAILS"&&Array.prototype.slice.apply(t.children).some(function(n){return n.tagName==="SUMMARY"});return r},IL=function(t,r){for(var n=0;n<t.length;n++)if(t[n].checked&&t[n].form===r)return t[n]},DL=function(t){if(!t.name)return!0;var r=t.form||Yc(t),n=function(c){return r.querySelectorAll('input[type="radio"][name="'+c+'"]')},o;if(typeof window<"u"&&typeof window.CSS<"u"&&typeof window.CSS.escape=="function")o=n(window.CSS.escape(t.name));else try{o=n(t.name)}catch(i){return console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s",i.message),!1}var a=IL(o,t.form);return!a||a===t},LL=function(t){return sS(t)&&t.type==="radio"},FL=function(t){return LL(t)&&!DL(t)},VL=function(t){var r,n=t&&Yc(t),o=(r=n)===null||r===void 0?void 0:r.host,a=!1;if(n&&n!==t){var i,c,p;for(a=!!((i=o)!==null&&i!==void 0&&(c=i.ownerDocument)!==null&&c!==void 0&&c.contains(o)||t!=null&&(p=t.ownerDocument)!==null&&p!==void 0&&p.contains(t));!a&&o;){var g,v,_;n=Yc(o),o=(g=n)===null||g===void 0?void 0:g.host,a=!!((v=o)!==null&&v!==void 0&&(_=v.ownerDocument)!==null&&_!==void 0&&_.contains(o))}}return a},_w=function(t){var r=t.getBoundingClientRect(),n=r.width,o=r.height;return n===0&&o===0},zL=function(t,r){var n=r.displayCheck,o=r.getShadowRoot;if(getComputedStyle(t).visibility==="hidden")return!0;var a=ys.call(t,"details>summary:first-of-type"),i=a?t.parentElement:t;if(ys.call(i,"details:not([open]) *"))return!0;if(!n||n==="full"||n==="legacy-full"){if(typeof o=="function"){for(var c=t;t;){var p=t.parentElement,g=Yc(t);if(p&&!p.shadowRoot&&o(p)===!0)return _w(t);t.assignedSlot?t=t.assignedSlot:!p&&g!==t.ownerDocument?t=g.host:t=p}t=c}if(VL(t))return!t.getClientRects().length;if(n!=="legacy-full")return!0}else if(n==="non-zero-area")return _w(t);return!1},BL=function(t){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(t.tagName))for(var r=t.parentElement;r;){if(r.tagName==="FIELDSET"&&r.disabled){for(var n=0;n<r.children.length;n++){var o=r.children.item(n);if(o.tagName==="LEGEND")return ys.call(r,"fieldset[disabled] *")?!0:!o.contains(t)}return!0}r=r.parentElement}return!1},WL=function(t,r){return!(r.disabled||Xc(r)||AL(r)||zL(r,t)||ML(r)||BL(r))},Tw=function(t,r){return!(FL(r)||lS(r)<0||!WL(t,r))},HL=function(t){var r=parseInt(t.getAttribute("tabindex"),10);return!!(isNaN(r)||r>=0)},UL=function e(t){var r=[],n=[];return t.forEach(function(o,a){var i=!!o.scopeParent,c=i?o.scopeParent:o,p=NL(c,i),g=i?e(o.candidates):c;p===0?i?r.push.apply(r,g):r.push(c):n.push({documentOrder:a,tabIndex:p,item:o,isScope:i,content:g})}),n.sort(jL).reduce(function(o,a){return a.isScope?o.push.apply(o,a.content):o.push(a.content),o},[]).concatLine truncated
|
||||
|
||||
More details: https://www.material-tailwind.com/docs/react/collapse
|
||||
`);var k=r.default.useRef(null),P=(0,g.useTheme)().navbar,N=P.styles,j=N.base.mobileNav;s=s??{},h=h??"";var D=(0,c.twMerge)((0,i.default)((0,p.default)(j)),h),F={unmount:{height:0,opacity:0,transition:{duration:.3,times:"[0.4, 0, 0.2, 1]"}},mount:{opacity:1,height:"".concat((E=k.current)===null||E===void 0?void 0:E.scrollHeight,"px"),transition:{duration:.3,times:"[0.4, 0, 0.2, 1]"}}},W=(0,a.default)(F,s),G=n.AnimatePresence,X=(0,o.useMergeRefs)([l,k]);return r.default.createElement(n.LazyMotion,{features:n.domAnimation},r.default.createElement(G,null,r.default.createElement(n.m.div,_({},w,{ref:X,className:D,initial:"unmount",exit:"unmount",animate:u?"mount":"unmount",variants:W}),m)))});x.displayName="MaterialTailwind.MobileNav",x.propTypes={open:v.propTypesOpen,animate:v.propTypesAnimate,className:v.propTypesClassName,children:v.propTypesChildren};var b=x})(QS);(function(e){Object.defineProperty(e,"__esModule",{value:!0});function t(l,u){for(var s in u)Object.defineProperty(l,s,{enumerable:!0,get:u[s]})}t(e,{Navbar:function(){return b},MobileNav:function(){return g.MobileNav},default:function(){return d}});var r=C(A),n=C(Fe),o=C($e),a=Le,i=C(kt),c=C(Me),p=je,g=QS,v=Pd;function _(l,u,s){return u in l?Object.defineProperty(l,u,{value:s,enumerable:!0,configurable:!0,writable:!0}):l[u]=s,l}function O(){return O=Object.assign||function(l){for(var u=1;u<arguments.length;u++){var s=arguments[u];for(var h in s)Object.prototype.hasOwnProperty.call(s,h)&&(l[h]=s[h])}return l},O.apply(this,arguments)}function C(l){return l&&l.__esModule?l:{default:l}}function T(l,u){if(l==null)return{};var s=x(l,u),h,m;if(Object.getOwnPropertySymbols){var w=Object.getOwnPropertySymbols(l);for(m=0;m<w.length;m++)h=w[m],!(u.indexOf(h)>=0)&&Object.prototype.propertyIsEnumerable.call(l,h)&&(s[h]=l[h])}return s}function x(l,u){if(l==null)return{};var s={},h=Object.keys(l),m,w;for(w=0;w<h.length;w++)m=h[w],!(u.indexOf(m)>=0)&&(s[m]=l[m]);return s}var b=r.default.forwardRef(function(l,u){var s=l.variant,h=l.color,m=l.shadow,w=l.blurred,E=l.fullWidth,k=l.className,P=l.children,N=T(l,["variant","color","shadow","blurred","fullWidth","className","children"]),j=(0,p.useTheme)().navbar,D=j.defaultProps,F=j.valid,W=j.styles,G=W.base,X=W.variants;s=s??D.variant,h=h??D.color,m=m??D.shadow,w=w??D.blurred,E=E??D.fullWidth,k=k??D.className;var U,B=(0,o.default)((0,c.default)(G.navbar.initial),(U={},_(U,(0,c.default)(G.navbar.shadow),m),_(U,(0,c.default)(G.navbar.blurred),w&&h==="white"),_(U,(0,c.default)(G.navbar.fullWidth),E),U)),H=(0,o.default)((0,c.default)(X[(0,i.default)(F.variants,s,"filled")][(0,i.default)(F.colors,h,"white")])),K=(0,a.twMerge)((0,o.default)(B,H),k);return r.default.createElement("nav",O({},N,{ref:u,className:K}),P)});b.propTypes={variant:n.default.oneOf(v.propTypesVariant),color:n.default.oneOf(v.propTypesColor),shadow:v.propTypesShadow,blurred:v.propTypesBlurred,fullWidth:v.propTypesFullWidth,className:v.propTypesClassName,children:v.propTypesChildren},b.displayName="MaterialTailwind.Navbar";var d=Object.assign(b,{MobileNav:g.MobileNav})})(XS);var JS={},Kd={},Qi={};(function(e){Object.defineProperty(e,"__esModule",{value:!0});function t(b,d){for(var l in d)Object.defineProperty(b,l,{enumerable:!0,get:d[l]})}t(e,{propTypesOpen:function(){return a},propTypesHandler:function(){return i},propTypesPlacement:function(){return c},propTypesOffset:function(){return p},propTypesDismiss:function(){return g},propTypesAnimate:function(){return v},propTypesContent:function(){return _},propTypesInteractive:function(){return O},propTypesClassName:function(){return C},propTypesChildren:function(){return T},propTypesContextValue:function(){return x}});var r=o(Fe),n=Ct;function o(b){return b&&b.__esModule?b:{default:b}}var a=r.default.bool,i=r.default.func,c=n.propTypesPlacements,p=n.propTypesOffsetType,g=n.propTypesDismissType,v=n.propTypesAnimation,_=r.default.node,O=r.default.bool,C=r.default.string,T=r.default.node.isRequired,x=r.default.shape({open:r.default.bool.isRequired,strategy:r.default.oneOf(["fixed","absolute"]).isRequired,x:r.default.number,y:r.default.number,context:r.default.instanceOf(Object).isRequired,reference:r.default.func.isRequired,floating:r.default.func.isRequired,getReferenceProps:r.default.func.isRequired,getFloatingProps:r.default.func.isRequired,appliedAnimation:v.isRequired,labelId:r.default.string.isRequired,descriptionId:r.default.string.isRequired}).isRequired})(Qi);(function(e){Object.defineProperty(e,"__esModule",{value:!0});function t(p,g){for(var v in g)Object.defineProperty(p,v,{enumerable:!0,get:g[v]})}t(e,{PopoverContext:function(){return a},usePopover:function(){return i},PopoverContextProvider:function(){return c}});var r=o(A),n=Qi;function o(p){return p&&p.__esModule?p:{default:p}}var a=r.default.createContext(null);a.displayName="MaterialTailwind.PopoverContext";function i(){var p=r.default.useContext(a);if(!p)throw new Error("usePopover() must be used within a Popover. It happens when you us
Line truncated
|
||||
`).forEach(function(i){o=i.indexOf(":"),r=i.substring(0,o).trim().toLowerCase(),n=i.substring(o+1).trim(),!(!r||t[r]&&GV[r])&&(r==="set-cookie"?t[r]?t[r].push(n):t[r]=[n]:t[r]=t[r]?t[r]+", "+n:n)}),t},rx=Symbol("internals");function Cl(e){return e&&String(e).trim().toLowerCase()}function ac(e){return e===!1||e==null?e:ce.isArray(e)?e.map(ac):String(e)}function YV(e){const t=Object.create(null),r=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let n;for(;n=r.exec(e);)t[n[1]]=n[2];return t}const XV=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function Ip(e,t,r,n,o){if(ce.isFunction(n))return n.call(this,t,r);if(o&&(t=r),!!ce.isString(t)){if(ce.isString(n))return t.indexOf(n)!==-1;if(ce.isRegExp(n))return n.test(t)}}function QV(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,r,n)=>r.toUpperCase()+n)}function JV(e,t){const r=ce.toCamelCase(" "+t);["get","set","has"].forEach(n=>{Object.defineProperty(e,n+r,{value:function(o,a,i){return this[n].call(this,t,o,a,i)},configurable:!0})})}class tf{constructor(t){t&&this.set(t)}set(t,r,n){const o=this;function a(c,p,g){const v=Cl(p);if(!v)throw new Error("header name must be a non-empty string");const _=ce.findKey(o,v);(!_||o[_]===void 0||g===!0||g===void 0&&o[_]!==!1)&&(o[_||p]=ac(c))}const i=(c,p)=>ce.forEach(c,(g,v)=>a(g,v,p));if(ce.isPlainObject(t)||t instanceof this.constructor)i(t,r);else if(ce.isString(t)&&(t=t.trim())&&!XV(t))i(KV(t),r);else if(ce.isHeaders(t))for(const[c,p]of t.entries())a(p,c,n);else t!=null&&a(r,t,n);return this}get(t,r){if(t=Cl(t),t){const n=ce.findKey(this,t);if(n){const o=this[n];if(!r)return o;if(r===!0)return YV(o);if(ce.isFunction(r))return r.call(this,o,n);if(ce.isRegExp(r))return r.exec(o);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,r){if(t=Cl(t),t){const n=ce.findKey(this,t);return!!(n&&this[n]!==void 0&&(!r||Ip(this,this[n],n,r)))}return!1}delete(t,r){const n=this;let o=!1;function a(i){if(i=Cl(i),i){const c=ce.findKey(n,i);c&&(!r||Ip(n,n[c],c,r))&&(delete n[c],o=!0)}}return ce.isArray(t)?t.forEach(a):a(t),o}clear(t){const r=Object.keys(this);let n=r.length,o=!1;for(;n--;){const a=r[n];(!t||Ip(this,this[a],a,t,!0))&&(delete this[a],o=!0)}return o}normalize(t){const r=this,n={};return ce.forEach(this,(o,a)=>{const i=ce.findKey(n,a);if(i){r[i]=ac(o),delete r[a];return}const c=t?QV(a):String(a).trim();c!==a&&delete r[a],r[c]=ac(o),n[c]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const r=Object.create(null);return ce.forEach(this,(n,o)=>{n!=null&&n!==!1&&(r[o]=t&&ce.isArray(n)?n.join(", "):n)}),r}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,r])=>t+": "+r).join(`
|
||||
`)}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...r){const n=new this(t);return r.forEach(o=>n.set(o)),n}static accessor(t){const n=(this[rx]=this[rx]={accessors:{}}).accessors,o=this.prototype;function a(i){const c=Cl(i);n[c]||(JV(o,i),n[c]=!0)}return ce.isArray(t)?t.forEach(a):a(t),this}}tf.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);ce.reduceDescriptors(tf.prototype,({value:e},t)=>{let r=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(n){this[r]=n}}});ce.freezeMethods(tf);const _n=tf;function Dp(e,t){const r=this||Ab,n=t||r,o=_n.from(n.headers);let a=n.data;return ce.forEach(e,function(c){a=c.call(r,a,o.normalize(),t?t.status:void 0)}),o.normalize(),a}function tk(e){return!!(e&&e.__CANCEL__)}function el(e,t,r){Xe.call(this,e??"canceled",Xe.ERR_CANCELED,t,r),this.name="CanceledError"}ce.inherits(el,Xe,{__CANCEL__:!0});function rk(e,t,r){const n=r.config.validateStatus;!r.status||!n||n(r.status)?e(r):t(new Xe("Request failed with status code "+r.status,[Xe.ERR_BAD_REQUEST,Xe.ERR_BAD_RESPONSE][Math.floor(r.status/100)-4],r.config,r.request,r))}function ZV(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function ez(e,t){e=e||10;const r=new Array(e),n=new Array(e);let o=0,a=0,i;return t=t!==void 0?t:1e3,function(p){const g=Date.now(),v=n[a];i||(i=g),r[o]=p,n[o]=g;let _=a,O=0;for(;_!==o;)O+=r[_++],_=_%e;if(o=(o+1)%e,o===a&&(a=(a+1)%e),g-i<t)return;const C=v&&g-v;return C?Math.round(O*1e3/C):void 0}}function tz(e,t){let r=0,n=1e3/t,o,a;const i=(g,v=Date.now())=>{r=v,o=null,a&&(clearTimeout(a),a=null),e.apply(null,g)};return[(...g)=>{const v=Date.now(),_=v-r;_>=n?i(g,v):(o=g,a||(a=setTimeout(()=>{a=null,i(o)},n-_)))},()=>o&&i(o)]}const ad=(e,t,r=3)=>{let n=0;const o=ez(50,250);return tz(a=>{const i=a.loaded,c=a.lengthComputable?a.total:void 0,p=i-n,g=o(p),v=i<=c;n=i;const _={loaded:i,total:c,progress:c?i/c:void 0,bytes:p,rate:g||void 0,estimated:g&&c&&v?(c-i)/g:void 0,event:a,lengthComputable:c!=null,[t?"download":"upload"]:!0};e(_)},r)},nx=(e,t)=>{const r=e!=null;return[n=>t[0]({lengthComputable:r,total:e,loaded:n}),t[1]]},ox=e=>(...t)=>ce.asap(()=>e(...t)),rz=Vr.hasStandardBrowserEnv?function(){const t=Vr.navigator&&/(msie|trident)/i.test(Vr.navigator.userAgent),r=document.createElement("a");let n;function o(a){let i=a;return t&&(r.setAttribute("href",i),i=r.href),r.setAttribute("href",i),{href:r.href,protocol:r.protocol?r.protocol.replace(/:$/,""):"",host:r.host,search:r.search?r.search.replace(/^\?/,""):"",hash:r.hash?r.hash.replace(/^#/,""):"",hostname:r.hostname,port:r.port,pathname:r.pathname.charAt(0)==="/"?r.pathname:"/"+r.pathname}}return n=o(window.location.href),function(i){const c=ce.isString(i)?o(i):i;return c.protocol===n.protocol&&c.host===n.host}}():function(){return function(){return!0}}(),nz=Vr.hasStandardBrowserEnv?{write(e,t,r,n,o,a){const i=[e+"="+encodeURIComponent(t)];ce.isNumber(r)&&i.push("expires="+new Date(r).toGMTString()),ce.isString(n)&&i.push("path="+n),ce.isString(o)&&i.push("domain="+o),a===!0&&i.push("secure"),document.cookie=i.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function oz(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function az(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function nk(e,t){return e&&!oz(t)?az(e,t):t}const ax=e=>e instanceof _n?{...e}:e;function Ea(e,t){t=t||{};const r={};function n(g,v,_){return ce.isPlainObject(g)&&ce.isPlainObject(v)?ce.merge.call({caseless:_},g,v):ce.isPlainObject(v)?ce.merge({},v):ce.isArray(v)?v.slice():v}function o(g,v,_){if(ce.isUndefined(v)){if(!ce.isUndefined(g))return n(void 0,g,_)}else return n(g,v,_)}function a(g,v){if(!ce.isUndefined(v))return n(void 0,v)}function i(g,v){if(ce.isUndefined(v)){if(!ce.isUndefined(g))return n(void 0,g)}else return n(void 0,v)}function c(g,v,_){if(_ in t)return n(g,v);if(_ in e)return n(void 0,g)}const p={url:a,method:a,data:a,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:c,headers:(g,v)=>o(ax(g),ax(v),!0)};return ce.forEach(Object.keys(Object.assign({},e,t)),function(v){const _=p[v]||o,O=_(e[v],t[v],v);ce.isUndefined(O)&&_!==c||(r[v]=O)}),r}const ok=e=>{const t=Ea({},e);let{data:r,withXSRFToken:n,xsrfHeaderName:o,xsrfCookieName:a,headers:i,auth:c}=t;t.headers=i=_n.from(i),t.url=JP(nk(t.baseURL,t.url),e.params,e.paramsSerializer),c&&i.set("Authorization","Basic "+btoa((c.username||"")+":"+(c.password?unescape(enco
Line truncated
|
||||
`+a.map(sx).join(`
|
||||
`):" "+sx(a[0]):"as no adapter specified";throw new Xe("There is no suitable adapter to dispatch the request "+i,"ERR_NOT_SUPPORT")}return n},adapters:gh};function Lp(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new el(null,e)}function ux(e){return Lp(e),e.headers=_n.from(e.headers),e.data=Dp.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),lk.getAdapter(e.adapter||Ab.adapter)(e).then(function(n){return Lp(e),n.data=Dp.call(e,e.transformResponse,n),n.headers=_n.from(n.headers),n},function(n){return tk(n)||(Lp(e),n&&n.response&&(n.response.data=Dp.call(e,e.transformResponse,n.response),n.response.headers=_n.from(n.response.headers))),Promise.reject(n)})}const sk="1.7.5",Mb={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{Mb[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}});const cx={};Mb.transitional=function(t,r,n){function o(a,i){return"[Axios v"+sk+"] Transitional option '"+a+"'"+i+(n?". "+n:"")}return(a,i,c)=>{if(t===!1)throw new Xe(o(i," has been removed"+(r?" in "+r:"")),Xe.ERR_DEPRECATED);return r&&!cx[i]&&(cx[i]=!0,console.warn(o(i," has been deprecated since v"+r+" and will be removed in the near future"))),t?t(a,i,c):!0}};function vz(e,t,r){if(typeof e!="object")throw new Xe("options must be an object",Xe.ERR_BAD_OPTION_VALUE);const n=Object.keys(e);let o=n.length;for(;o-- >0;){const a=n[o],i=t[a];if(i){const c=e[a],p=c===void 0||i(c,a,e);if(p!==!0)throw new Xe("option "+a+" must be "+p,Xe.ERR_BAD_OPTION_VALUE);continue}if(r!==!0)throw new Xe("Unknown option "+a,Xe.ERR_BAD_OPTION)}}const bh={assertOptions:vz,validators:Mb},To=bh.validators;class ld{constructor(t){this.defaults=t,this.interceptors={request:new tx,response:new tx}}async request(t,r){try{return await this._request(t,r)}catch(n){if(n instanceof Error){let o;Error.captureStackTrace?Error.captureStackTrace(o={}):o=new Error;const a=o.stack?o.stack.replace(/^.+\n/,""):"";try{n.stack?a&&!String(n.stack).endsWith(a.replace(/^.+\n.+\n/,""))&&(n.stack+=`
|
||||
`+a):n.stack=a}catch{}}throw n}}_request(t,r){typeof t=="string"?(r=r||{},r.url=t):r=t||{},r=Ea(this.defaults,r);const{transitional:n,paramsSerializer:o,headers:a}=r;n!==void 0&&bh.assertOptions(n,{silentJSONParsing:To.transitional(To.boolean),forcedJSONParsing:To.transitional(To.boolean),clarifyTimeoutError:To.transitional(To.boolean)},!1),o!=null&&(ce.isFunction(o)?r.paramsSerializer={serialize:o}:bh.assertOptions(o,{encode:To.function,serialize:To.function},!0)),r.method=(r.method||this.defaults.method||"get").toLowerCase();let i=a&&ce.merge(a.common,a[r.method]);a&&ce.forEach(["delete","get","head","post","put","patch","common"],T=>{delete a[T]}),r.headers=_n.concat(i,a);const c=[];let p=!0;this.interceptors.request.forEach(function(x){typeof x.runWhen=="function"&&x.runWhen(r)===!1||(p=p&&x.synchronous,c.unshift(x.fulfilled,x.rejected))});const g=[];this.interceptors.response.forEach(function(x){g.push(x.fulfilled,x.rejected)});let v,_=0,O;if(!p){const T=[ux.bind(this),void 0];for(T.unshift.apply(T,c),T.push.apply(T,g),O=T.length,v=Promise.resolve(r);_<O;)v=v.then(T[_++],T[_++]);return v}O=c.length;let C=r;for(_=0;_<O;){const T=c[_++],x=c[_++];try{C=T(C)}catch(b){x.call(this,b);break}}try{v=ux.call(this,C)}catch(T){return Promise.reject(T)}for(_=0,O=g.length;_<O;)v=v.then(g[_++],g[_++]);return v}getUri(t){t=Ea(this.defaults,t);const r=nk(t.baseURL,t.url);return JP(r,t.params,t.paramsSerializer)}}ce.forEach(["delete","get","head","options"],function(t){ld.prototype[t]=function(r,n){return this.request(Ea(n||{},{method:t,url:r,data:(n||{}).data}))}});ce.forEach(["post","put","patch"],function(t){function r(n){return function(a,i,c){return this.request(Ea(c||{},{method:t,headers:n?{"Content-Type":"multipart/form-data"}:{},url:a,data:i}))}}ld.prototype[t]=r(),ld.prototype[t+"Form"]=r(!0)});const ic=ld;class Ib{constructor(t){if(typeof t!="function")throw new TypeError("executor must be a function.");let r;this.promise=new Promise(function(a){r=a});const n=this;this.promise.then(o=>{if(!n._listeners)return;let a=n._listeners.length;for(;a-- >0;)n._listeners[a](o);n._listeners=null}),this.promise.then=o=>{let a;const i=new Promise(c=>{n.subscribe(c),a=c}).then(o);return i.cancel=function(){n.unsubscribe(a)},i},t(function(a,i,c){n.reason||(n.reason=new el(a,i,c),r(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const r=this._listeners.indexOf(t);r!==-1&&this._listeners.splice(r,1)}static source(){let t;return{token:new Ib(function(o){t=o}),cancel:t}}}const mz=Ib;function yz(e){return function(r){return e.apply(null,r)}}function wz(e){return ce.isObject(e)&&e.isAxiosError===!0}const vh={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(vh).forEach(([e,t])=>{vh[t]=e});const xz=vh;function uk(e){const t=new ic(e),r=zP(ic.prototype.request,t);return ce.extend(r,ic.prototype,t,{allOwnKeys:!0}),ce.extend(r,t,null,{allOwnKeys:!0}),r.create=function(o){return uk(Ea(e,o))},r}const Ht=uk(Ab);Ht.Axios=ic;Ht.CanceledError=el;Ht.CancelToken=mz;Ht.isCancel=tk;Ht.VERSION=sk;Ht.toFormData=ef;Ht.AxiosError=Xe;Ht.Cancel=Ht.CanceledError;Ht.all=function(t){return Promise.all(t)};Ht.spread=yz;Ht.isAxiosError=wz;Ht.mergeConfig=Ea;Ht.AxiosHeaders=_n;Ht.formToJSON=e=>ek(ce.isHTMLForm(e)?new FormData(e):e);Ht.getAdapter=lk.getAdapter;Ht.HttpStatusCode=xz;Ht.default=Ht;const Nt=Ht,Bn=Object.create(null);Bn.open="0";Bn.close="1";Bn.ping="2";Bn.pong="3";Bn.message="4";Bn.upgrade="5";Bn.noop="6";const lc=Object.create(null);Object.keys(Bn).forEach(e=>{lc[Bn[e]]=e});const mh={type:"error",data:"parser error"},ck=typeof Blob=="function"||typeof Blob<"u"&&Object.prototype.toString.call(Blob)==="[object BlobConstructor]",dk=typeof Array
Line truncated
|
||||
${Se?"border-purple-500 ring-1 ring-purple-500/40":"border-transparent"}
|
||||
${!_e||ve?"opacity-75 bg-stormGrey-200/20":""}`,children:[I.jsxs("div",{className:"flex items-center space-x-4",id:"left",children:[I.jsx("input",{type:"checkbox",checked:Se,onChange:()=>Ae(le.Id,!_e),className:`h-5 w-5 text-purple-500 focus:ring-purple-400 border-gray-600 bg-gray-900 rounded ${_e?"":"opacity-40 cursor-not-allowed"}`,disabled:!_e}),I.jsx("div",{className:`w-12 h-12 flex items-center justify-center rounded-full
|
||||
${le.updateStatus==="✅"?"bg-mossGreen-600":le.updateStatus==="⚠️"?"bg-warmAmberGlow-400":"bg-sunsetCoral-500"}`}),I.jsxs("div",{children:[I.jsx("p",{className:"text-lg antialiased font-sans font-semibold leading-normal text-inherit",children:le.Name}),I.jsxs("p",{className:"text-sm antialiased font-sans font-light leading-normal text-inherit",children:["ID: ",le.Id]}),le.duplicateName&&I.jsx("p",{className:"text-xs text-amber-700",children:"⚠️ Doppelter Name erkannt"})]})]}),I.jsx("div",{className:"ml-auto flex flex-col items-end gap-1 text-sm",id:"right",children:Ve?I.jsxs(I.Fragment,{children:[I.jsx("span",{className:"antialiased font-sans font-light leading-normal text-xs uppercase tracking-wide text-warmAmberGlow-600",children:"Redeploy"}),I.jsx("span",{className:"text-warmAmberGlow-500",children:"läuft…"})]}):Ee?I.jsxs(I.Fragment,{children:[I.jsx("span",{className:"antialiased font-sans font-light leading-normal text-xs uppercase tracking-wide text-warmAmberGlow-600",children:"Redeploy"}),I.jsx("span",{className:"text-warmAmberGlow-500",children:"in Warteliste…"})]}):fe?I.jsxs(I.Fragment,{children:[I.jsx("span",{className:"antialiased font-sans font-light leading-normal text-xs uppercase tracking-wide text-stormGrey-500",children:"System"}),I.jsx("span",{className:"text-gray-300",children:"Redeploy deaktiviert"})]}):ee?I.jsxs(I.Fragment,{children:[I.jsx("span",{className:"antialiased font-sans font-light leading-normal text-xs uppercase tracking-wide text-stormGrey-500",children:"Status"}),I.jsx("span",{className:"text-mossGreen-600",children:"Aktuell"})]}):I.jsx(ge.Button,{onClick:()=>rt(le.Id),disabled:ve,className:"disabled:opacity-50 disabled:cursor-not-allowed",children:"Redeploy"})})]})},le.Id)})}),I.jsx(kk,{disabled:r||!!o})]})}const k6={idle:"Bereit",running:"Läuft",success:"Erfolgreich",error:"Fehlgeschlagen"},Sl={idle:"bg-stormGrey-700 text-gray-200",running:"bg-arcticBlue-600 text-white",success:"bg-mossGreen-600 text-white",error:"bg-sunsetCoral-600 text-white"},E6={initializing:"Vorbereitung","activating-maintenance":"Wartungsmodus aktivieren","executing-script":"Skript wird ausgeführt",waiting:"Warte auf Portainer",completed:"Abgeschlossen",failed:"Fehlgeschlagen"},R6={info:"text-arcticBlue-700",success:"text-mossGreen-700",warning:"text-warmAmberGlow-700",error:"text-sunsetCoral-700",stdout:"text-stormGrey-700",stderr:"text-warmAmberGlow-700",debug:"text-lavenderSmoke-700"},N6=e=>{if(!e)return"-";const t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString("de-DE",{hour:"2-digit",minute:"2-digit",second:"2-digit"})},ua=e=>{if(!e&&e!==0)return"-";const r=(n=>{if(n instanceof Date)return n;if(typeof n=="number"){const o=n>1e12?n:n*1e3;return new Date(o)}if(typeof n=="string"){const o=Number(n);if(!Number.isNaN(o)){const a=o>1e12?o:o*1e3;return new Date(a)}return new Date(n)}return null})(e);return!r||Number.isNaN(r.getTime())?String(e):r.toLocaleString("de-DE",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"})},mx=e=>e===1?"Git":e===2?"Compose":e??"-",Wp=()=>({host:"",port:"22",username:"",password:"",extraSshArgs:""});function j6(){var Wa,fo,po;const{showToast:e}=Ck(),{maintenance:t,update:r,script:n,ssh:o,loading:a,error:i,setMaintenanceMode:c,triggerUpdate:p,saveScript:g,resetScript:v,saveSshConfig:_,deleteSshConfig:O,testSshConnection:C}=Sk(),T=!!(t!=null&&t.active),x=t==null?void 0:t.message,b=(Wa=t==null?void 0:t.extra)==null?void 0:Wa.type,d=!!(r!=null&&r.running),[l,u]=A.useState(""),[s,h]=A.useState(!1),[m,w]=A.useState(!1),[E,k]=A.useState(""),[P,N]=A.useState(!1),[j,D]=A.useState(()=>Wp()),[F,W]=A.useState(!1),[G,X]=A.useState(!1),[U,B]=A.useState(!1),[H,K]=A.useState(!1),[Q,oe]=A.useState(!1),[ue,ie]=A.useState(null);A.useEffect(()=>{if(!n)return;const we=n.custom??n.default??n.effective??"";u(we)},[n]),A.useEffect(()=>{if(!o){D(Wp()),W(!1),X(!1),ie(null);return}D({host:o.host??"",port:String(o.port??"22"),username:o.username??"",password:"",extraSshArgs:Array.isArray(o.extraSshArgs)?o.extraSshArgs.join(`
|
||||
`):""}),W(!!o.passwordStored),X(!1),ie(null)},[o]);const ne=A.useMemo(()=>n?n.source==="custom"&&typeof n.custom=="string"?n.custom:n.default??n.effective??"":"",[n]),be=n?l!==ne:!1,pe=(n==null?void 0:n.source)==="custom"?"Benutzerdefiniert":"Standard",[ae,he]=A.useState([]),[de,Oe]=A.useState(!0),[Ae,Ce]=A.useState(""),[Te,ke]=A.useState(!1),[Ke,rt]=A.useState(null),[ft,ut]=A.useState(null),nt=A.useRef(null),[He,wt]=A.useState(null),[ot,Je]=A.useState(!0),[le,me]=A.useState(""),[Ee,Ve]=A.useState(!1),[ve,Se]=A.useState(null),ee=A.useRef(null),fe=A.useCallback(async({silent:we=!1}={})=>{if(ee.current)return ee.current;const ze=(async()=>{var Be,et;we?Ve(!0):Je(!0),me("");try{const Vt=(await Nt.get("/api/maintenance/portainer-status")).data??{};wt(Vt),Se(new Date)}catch(pt){const Vt=((et=(Be=pt.response)==null?void 0:Be.data)==null?void 0:et.error)||pt.message||"Fehler beim Prüfen des Portainer-Status";me(Vt),e({variant:"error",title:"Statusaktualisierung fehlgeschlagen",description:Vt})}finally{we?Ve(!1):Je(!1),ee.current=null}})();return ee.current=ze,ze},[e]),_e=A.useCallback(async({silent:we=!1}={})=>{if(T||d){he([]),Ce("Wartungsmodus aktiv – Duplikat-Verwaltung ist vorübergehend deaktiviert."),Oe(!1),ke(!1);return}if(nt.current)return nt.current;const ze=(async()=>{var Be,et,pt;we?ke(!0):Oe(!0),Ce("");try{const Et=(await Nt.get("/api/maintenance/duplicates")).data,jr=Array.isArray(Et)?Et:(Et==null?void 0:Et.items)??[];he(jr),ut(new Date)}catch(Vt){if(((Be=Vt.response)==null?void 0:Be.status)===423){const Et="Wartungsmodus aktiv – Duplikat-Verwaltung ist vorübergehend deaktiviert.";he([]),Ce(Et),e({variant:"warning",title:"Duplikat-Verwaltung gesperrt",description:Et})}else{const Et=((pt=(et=Vt.response)==null?void 0:et.data)==null?void 0:pt.error)||Vt.message||"Fehler beim Laden der Wartungsdaten";Ce(Et),e({variant:"error",title:"Duplikate konnten nicht geladen werden",description:Et})}}finally{we?ke(!1):Oe(!1),nt.current=null}})();return nt.current=ze,ze},[T,d,e]);A.useEffect(()=>{fe()},[fe]),A.useEffect(()=>{_e()},[_e]);const Ie=A.useMemo(()=>{const we=Array.isArray(ae)?ae.length:0,ze=Array.isArray(ae)?ae.reduce((Be,et)=>{var pt;return Be+(((pt=et==null?void 0:et.duplicates)==null?void 0:pt.length)||0)},0):0;return{groups:we,duplicateCount:ze}},[ae]),Ze=A.useCallback((we,ze)=>{D(Be=>({...Be,[we]:ze})),we==="password"&&W(!1)},[]),at=A.useMemo(()=>{const we={host:j.host.trim(),port:Number.parseInt(j.port,10)||22,username:j.username.trim(),extraSshArgs:(j.extraSshArgs||"").split(/\r?\n/).map(Be=>Be.trim()).filter(Boolean)},ze=j.password??"";return ze?we.password=ze:F||(we.password=""),we},[j,F]),qe=A.useCallback(async()=>{var we,ze;if(n)try{h(!0),await g(l),e({variant:"success",title:"Skript gespeichert",description:"Das benutzerdefinierte Portainer-Update-Skript wurde aktualisiert."})}catch(Be){const et=((ze=(we=Be.response)==null?void 0:we.data)==null?void 0:ze.error)||Be.message||"Skript konnte nicht gespeichert werden";e({variant:"error",title:"Speichern fehlgeschlagen",description:et})}finally{h(!1)}},[g,l,n,e]),mt=A.useCallback(async()=>{var we,ze;try{h(!0),await v(),e({variant:"info",title:"Standardskript wiederhergestellt",description:"Es wird wieder das Standard-Update-Skript verwendet."})}catch(Be){const et=((ze=(we=Be.response)==null?void 0:we.data)==null?void 0:ze.error)||Be.message||"Standardskript konnte nicht wiederhergestellt werden";e({variant:"error",title:"Zurücksetzen fehlgeschlagen",description:et})}finally{h(!1)}},[v,e]),tr=A.useCallback(async()=>{var we,ze;try{B(!0),await _(at),ie(null),X(!1),e({variant:"success",title:"SSH-Konfiguration gespeichert",description:"Verbindungseinstellungen wurden aktualisiert."})}catch(Be){const et=((ze=(we=Be.response)==null?void 0:we.data)==null?void 0:ze.error)||Be.message||"SSH-Konfiguration konnte nicht gespeichert werden";e({variant:"error",title:"Speichern fehlgeschlagen",description:et})}finally{B(!1)}},[at,_,e]),lr=A.useCallback(async()=>{var we,ze;try{K(!0);const Be=await C(at);ie({success:!0,timestamp:new Date,details:Be==null?void 0:Be.result}),e({variant:"success",title:"SSH-Verbindung erfolgreich",description:"Verbindung zum Portainer-Host wurde hergestellt."})}catch(Be){const et=((ze=(we=Be.response)==null?void 0:we.data)==null?void 0:ze.error)||Be.message||"SSH-Verbindung fehlgeschlagen";ie({success:!1,timestamp:new Date,error:et}),e({variant:"error",title:"SSH-Test fehlgeschlagen",description:et})}finally{K(!1)}},[at,C,e]),sn=A.useCallback(async()=>{var we,ze;try{oe(!0),await O(),D(Wp()),W(!1),X(!1),ie(null),e({variant:"info",title:"SSH-Konfiguration gelöscht",description:"Die Verbindungseinstellungen wurden zurückgesetzt."})}catch(Be){const et=((ze=(we=Be.response)==null?void 0:we.data)==null?void 0:ze.error)||Be.message||"SSH-Konfiguration konnte nicht gelöscht werden";e({variant:"error",title:"Löschen fehlgeschlagen",description:et})}finally{oe(!1)}},[O,e]),Kt=A.useCallback(async we=>{var ze,Be;if(!(a||P)&&we!==T){if(
Line truncated
|
||||
Zielversion: ${we}.
|
||||
Während des Updates befindet sich StackPulse im Wartungsmodus.
|
||||
Fortfahren?`)))try{k(""),w(!0),await p(),e({variant:"info",title:"Update gestartet",description:"Das Portainer-Update wurde gestartet."})}catch(et){const pt=((Be=(ze=et.response)==null?void 0:ze.data)==null?void 0:Be.error)||et.message||"Portainer-Update konnte nicht gestartet werden";k(pt),e({variant:"error",title:"Update fehlgeschlagen",description:pt})}finally{w(!1)}},[T,d,He,p,e]),lo=A.useCallback(async we=>{var pt,Vt,Et,jr;if(!we)return;if(T||d){e({variant:"warning",title:"Aktion nicht möglich",description:"Während des Wartungsmodus sind Bereinigungen deaktiviert."});return}const ze=(pt=we.canonical)==null?void 0:pt.Id;if(!ze)return;const Be=(we.duplicates||[]).map(Yt=>Yt.Id).filter(Boolean);if(!Be.length)return;const et=((Vt=we.canonical)==null?void 0:Vt.Name)||we.name||`Stack ${ze}`;if(!(typeof window<"u"&&!window.confirm(`Bereinigung für "${et}" starten?
|
||||
Es werden ${Be.length} Duplikate entfernt: ${Be.join(", ")}`))){rt(String(ze));try{const qr=(await Nt.post("/api/maintenance/duplicates/cleanup",{canonicalId:ze,duplicateIds:Be})).data??{};if(qr.success===!1)throw new Error(qr.error||"Bereinigung fehlgeschlagen");const ta=Array.isArray(qr.results)?qr.results.filter(un=>un.status==="deleted").map(un=>un.id):Be;e({variant:"success",title:"Bereinigung abgeschlossen",description:`${et} – entfernte IDs: ${ta.join(", ")}`}),await _e({silent:!0})}catch(Yt){const qr=((jr=(Et=Yt.response)==null?void 0:Et.data)==null?void 0:jr.error)||Yt.message||"Bereinigung fehlgeschlagen";e({variant:"error",title:"Bereinigung fehlgeschlagen",description:qr})}finally{rt(null)}}},[_e,T,e,d]);t!=null&&t.activatedAt&&ua(t.activatedAt),t!=null&&t.updatedAt&&ua(t.updatedAt);const Ur=T||d,so=(r==null?void 0:r.status)??(d?"running":"idle"),En=k6[so]??so,Zo=Sl[so]??Sl.idle,xr=r!=null&&r.stage?E6[r.stage]??r.stage:"–",Hn=(r==null?void 0:r.logs)??[],uo=(r==null?void 0:r.targetVersion)??"-",za=(r==null?void 0:r.resultVersion)??"-",co=r!=null&&r.startedAt?ua(r.startedAt):"-",$r=r!=null&&r.finishedAt?ua(r.finishedAt):"-",Ba=(r==null?void 0:r.message)??(d?"Update läuft…":""),ea=d||s||a;return I.jsxs("div",{className:"mt-12 mb-8 flex flex-col gap-12",children:[(T||d)&&I.jsx("div",{className:"rounded-lg border border-cyan-500/60 bg-cyan-900/30 px-4 py-3 text-sm text-bluegray-100",children:I.jsxs("div",{className:"flex flex-col gap-1",children:[I.jsxs("span",{children:["Wartungsmodus aktiv",x?` – ${x}`:d?" – Portainer-Update läuft":"","."]}),d&&I.jsxs("span",{className:"text-xs text-indigo-900",children:["Phase: ",xr]})]})}),I.jsxs(ge.Card,{children:[I.jsx(ge.CardHeader,{variant:"gradient",color:"gray",className:"mb-5 p-4",children:I.jsx(ge.Typography,{variant:"h6",color:"white",className:"flex items-center justify-between",children:I.jsx("span",{children:"Wartungsmodus"})})}),I.jsxs(ge.CardBody,{className:"flex flex-col gap-4 p-4",children:[I.jsxs("div",{className:"flex items-start justify-between gap-4",children:[I.jsx("div",{className:"space-y-1",children:I.jsx("p",{className:"text-sm antialiased font-sans text-sm font-light leading-normal text-inherit",children:"Schaltet StackPulse für Benutzer in den Wartungsmodus."})}),I.jsx(ge.Switch,{checked:T,disabled:P||a||d,onChange:we=>Kt(we.target.checked),ripple:!1,color:"amber"})]}),P&&I.jsx("p",{className:"text-xs text-stormGrey-500",children:"Wartungsmodus wird aktualisiert…"})]})]}),I.jsxs(ge.Card,{children:[I.jsx(ge.CardHeader,{variant:"gradient",color:"gray",className:"mb-5 p-4",children:I.jsx(ge.Typography,{variant:"h6",color:"white",className:"flex items-center justify-between",children:I.jsx("span",{children:"Portainer"})})}),I.jsxs(ge.CardBody,{className:"flex flex-col gap-4 p-4 pt-0",children:[I.jsxs("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[I.jsxs("div",{children:[I.jsx("h2",{className:"block antialiased font-sans text-lg font-semibold",children:"Portainer Status"}),I.jsx("p",{className:"block antialiased font-sans text-sm font-light leading-normal text-inherit",children:ot?"Status wird geprüft…":le||(d?"Portainer wird aktuell aktualisiert.":(He==null?void 0:He.updateAvailable)===!0?"Es ist ein Update für Portainer verfügbar.":"Portainer ist auf dem aktuellen Stand.")}),ve&&!ot&&I.jsxs("p",{className:"mt-1 text-xs text-stormGrey-500 block antialiased font-sans",children:["Stand: ",ve.toLocaleString("de-DE",{hour:"2-digit",minute:"2-digit",second:"2-digit"})]})]}),I.jsx("div",{className:"flex items-center gap-3",children:I.jsx(ge.Button,{onClick:()=>fe({silent:!1}),disabled:ot||Ee,className:"w-full",children:"Status aktualisieren"})})]}),I.jsx("div",{className:"flex flex-col gap-4 mt-5 space-y-4 block antialiased font-sans text-sm font-light leading-normal text-inherit",children:!ot&&!le&&He&&I.jsxs("div",{className:"",children:[I.jsxs("div",{className:"flex items-center justify-between space-y-2",children:[I.jsx("span",{children:"Installierte Version"}),I.jsx("span",{className:"font-medium",children:He.currentVersion??"Unbekannt"})]}),I.jsxs("div",{className:"flex items-center justify-between space-y-2",children:[I.jsx("span",{children:"Neueste Version"}),I.jsx("span",{className:"font-medium",children:He.latestVersion??"Unbekannt"})]}),I.jsxs("div",{className:"flex items-center justify-between space-y-2",children:[I.jsx("span",{children:"Status"}),I.jsx("span",{className:`rounded-full px-3 py-0.5 text-xs font-semibold ${He.updateAvailable===!0?Sl.error:He.updateAvailable===!1?Sl.success:Sl.idle}`,children:He.updateAvailable===!0?"Update verfügbar":He.updateAvailable===!1?"Aktuell":"Unbekannt"})]}),He.edition&&I.jsxs("div",{className:"flex items-center justify-between",children:[I.jsx("span",{className:"text-stormGrey-400",children:"Edition"}),I.jsx("span",{className:"font-medium",children:He.edition})]}),He.build&&I.jsxs("div",{className:"flex items-center justify-
Line truncated
|
||||
@@ -0,0 +1 @@
|
||||
*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#eee}:before,:after{--tw-content: ""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Roboto,sans-serif;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#bdbdbd}input::placeholder,textarea::placeholder{opacity:1;color:#bdbdbd}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(33 150 243 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(33 150 243 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width: 540px){.container{max-width:540px}}@media (min-width: 720px){.container{max-width:720px}}@media (min-width: 960px){.container{max-width:960px}}@media (min-width: 1140px){.container{max-width:1140px}}@media (min-width: 1320px){.container{max-width:1320px}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.\!invisible{visibility:hidden!important}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.\!absolute{position:absolute!important}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bLine truncated
|
||||
@@ -1,48 +0,0 @@
|
||||
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const o of i)if(o.type==="childList")for(const s of o.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&r(s)}).observe(document,{childList:!0,subtree:!0});function n(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(i){if(i.ep)return;i.ep=!0;const o=n(i);fetch(i.href,o)}})();function Pd(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Da={exports:{}},$i={},za={exports:{}},A={};/**
|
||||
* @license React
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var vr=Symbol.for("react.element"),Ld=Symbol.for("react.portal"),Ad=Symbol.for("react.fragment"),Dd=Symbol.for("react.strict_mode"),zd=Symbol.for("react.profiler"),Fd=Symbol.for("react.provider"),Bd=Symbol.for("react.context"),Ud=Symbol.for("react.forward_ref"),Id=Symbol.for("react.suspense"),Md=Symbol.for("react.memo"),jd=Symbol.for("react.lazy"),su=Symbol.iterator;function $d(e){return e===null||typeof e!="object"?null:(e=su&&e[su]||e["@@iterator"],typeof e=="function"?e:null)}var Fa={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Ba=Object.assign,Ua={};function kn(e,t,n){this.props=e,this.context=t,this.refs=Ua,this.updater=n||Fa}kn.prototype.isReactComponent={};kn.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};kn.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function Ia(){}Ia.prototype=kn.prototype;function el(e,t,n){this.props=e,this.context=t,this.refs=Ua,this.updater=n||Fa}var tl=el.prototype=new Ia;tl.constructor=el;Ba(tl,kn.prototype);tl.isPureReactComponent=!0;var lu=Array.isArray,Ma=Object.prototype.hasOwnProperty,nl={current:null},ja={key:!0,ref:!0,__self:!0,__source:!0};function $a(e,t,n){var r,i={},o=null,s=null;if(t!=null)for(r in t.ref!==void 0&&(s=t.ref),t.key!==void 0&&(o=""+t.key),t)Ma.call(t,r)&&!ja.hasOwnProperty(r)&&(i[r]=t[r]);var l=arguments.length-2;if(l===1)i.children=n;else if(1<l){for(var u=Array(l),a=0;a<l;a++)u[a]=arguments[a+2];i.children=u}if(e&&e.defaultProps)for(r in l=e.defaultProps,l)i[r]===void 0&&(i[r]=l[r]);return{$$typeof:vr,type:e,key:o,ref:s,props:i,_owner:nl.current}}function Vd(e,t){return{$$typeof:vr,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}function rl(e){return typeof e=="object"&&e!==null&&e.$$typeof===vr}function Hd(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,function(n){return t[n]})}var uu=/\/+/g;function yo(e,t){return typeof e=="object"&&e!==null&&e.key!=null?Hd(""+e.key):t.toString(36)}function Kr(e,t,n,r,i){var o=typeof e;(o==="undefined"||o==="boolean")&&(e=null);var s=!1;if(e===null)s=!0;else switch(o){case"string":case"number":s=!0;break;case"object":switch(e.$$typeof){case vr:case Ld:s=!0}}if(s)return s=e,i=i(s),e=r===""?"."+yo(s,0):r,lu(i)?(n="",e!=null&&(n=e.replace(uu,"$&/")+"/"),Kr(i,t,n,"",function(a){return a})):i!=null&&(rl(i)&&(i=Vd(i,n+(!i.key||s&&s.key===i.key?"":(""+i.key).replace(uu,"$&/")+"/")+e)),t.push(i)),1;if(s=0,r=r===""?".":r+":",lu(e))for(var l=0;l<e.length;l++){o=e[l];var u=r+yo(o,l);s+=Kr(o,t,n,u,i)}else if(u=$d(e),typeof u=="function")for(e=u.call(e),l=0;!(o=e.next()).done;)o=o.value,u=r+yo(o,l++),s+=Kr(o,t,n,u,i);else if(o==="object")throw t=String(e),Error("Objects are not valid as a React child (found: "+(t==="[object Object]"?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return s}function Nr(e,t,n){if(e==null)return e;var r=[],i=0;return Kr(e,r,"","",function(o){return t.call(n,o,i++)}),r}function Wd(e){if(e._status===-1){var t=e._result;t=t(),t.then(function(n){(e._status===0||e._status===-1)&&(e._status=1,e._result=n)},function(n){(e._status===0||e._status===-1)&&(e._status=2,e._result=n)}),e._status===-1&&(e._status=0,e._result=t)}if(e._status===1)return e._result.default;throw e._result}var pe={current:null},Xr={transition:null},qd={ReactCurrentDispatcher:pe,ReactCurrentBatchConfig:Xr,ReactCurrentOwner:nl};function Va(){throw Error("act(...) is not supported in production builds of React.")}A.Children={map:Nr,forEach:function(e,t,n){Nr(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return Nr(e,function(){t++}),t},toArray:function(e){return Nr(e,function(t){return t})||[]},only:function(e){if(!rl(e))throw Error("React.Children.only expected to receive a single React element child.");return e}};A.Component=kn;A.Fragment=Ad;A.Profiler=zd;A.PureComponent=el;A.StrictMode=Dd;A.Suspense=Id;A.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=qd;A.act=Va;A.cloneElement=function(e,t,n){if(e==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var r=Ba({},e.props),i=e.key,o=e.ref,s=e._owner;if(t!=null){if(t.ref!==void 0&&(o=t.ref,s=nl.current),t.key!==void 0&&(i=""+t.key),e.type&&e.type.defaultProps)var l=e.type.defaultProps;for(u in t)Ma.call(t,u)&&!ja.hasOwnProperty(u)&&(r[u]=t[u]===void 0&&l!==void 0?l[u]:t[u])}var u=arguments.length-2;if(u===1)r.children=n;else if(1<u){l=Array(u);for(var a=0;a<u;a++)l[a]=arguments[a+2];r.children=l}return{$$typeof:vr,type:e.type,key:i,ref:o,props:r,_owner:s}};A.createContext=function(e){return e={$$typeof:Bd,_currentValue:e,_currentValue2:e,_threadCount:0,ProviderLine truncated
|
||||
* @license React
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var Kd=be,Xd=Symbol.for("react.element"),Yd=Symbol.for("react.fragment"),Jd=Object.prototype.hasOwnProperty,Gd=Kd.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Zd={key:!0,ref:!0,__self:!0,__source:!0};function Ha(e,t,n){var r,i={},o=null,s=null;n!==void 0&&(o=""+n),t.key!==void 0&&(o=""+t.key),t.ref!==void 0&&(s=t.ref);for(r in t)Jd.call(t,r)&&!Zd.hasOwnProperty(r)&&(i[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps,t)i[r]===void 0&&(i[r]=t[r]);return{$$typeof:Xd,type:e,key:o,ref:s,props:i,_owner:Gd.current}}$i.Fragment=Yd;$i.jsx=Ha;$i.jsxs=Ha;Da.exports=$i;var G=Da.exports,Yo={},Wa={exports:{}},Ce={},qa={exports:{}},Qa={};/**
|
||||
* @license React
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/(function(e){function t(T,P){var L=T.length;T.push(P);e:for(;0<L;){var Q=L-1>>>1,ee=T[Q];if(0<i(ee,P))T[Q]=P,T[L]=ee,L=Q;else break e}}function n(T){return T.length===0?null:T[0]}function r(T){if(T.length===0)return null;var P=T[0],L=T.pop();if(L!==P){T[0]=L;e:for(var Q=0,ee=T.length,Rr=ee>>>1;Q<Rr;){var Pt=2*(Q+1)-1,mo=T[Pt],Lt=Pt+1,Tr=T[Lt];if(0>i(mo,L))Lt<ee&&0>i(Tr,mo)?(T[Q]=Tr,T[Lt]=L,Q=Lt):(T[Q]=mo,T[Pt]=L,Q=Pt);else if(Lt<ee&&0>i(Tr,L))T[Q]=Tr,T[Lt]=L,Q=Lt;else break e}}return P}function i(T,P){var L=T.sortIndex-P.sortIndex;return L!==0?L:T.id-P.id}if(typeof performance=="object"&&typeof performance.now=="function"){var o=performance;e.unstable_now=function(){return o.now()}}else{var s=Date,l=s.now();e.unstable_now=function(){return s.now()-l}}var u=[],a=[],c=1,p=null,m=3,S=!1,g=!1,v=!1,k=typeof setTimeout=="function"?setTimeout:null,d=typeof clearTimeout=="function"?clearTimeout:null,f=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function h(T){for(var P=n(a);P!==null;){if(P.callback===null)r(a);else if(P.startTime<=T)r(a),P.sortIndex=P.expirationTime,t(u,P);else break;P=n(a)}}function w(T){if(v=!1,h(T),!g)if(n(u)!==null)g=!0,po(_);else{var P=n(a);P!==null&&ho(w,P.startTime-T)}}function _(T,P){g=!1,v&&(v=!1,d(N),N=-1),S=!0;var L=m;try{for(h(P),p=n(u);p!==null&&(!(p.expirationTime>P)||T&&!ze());){var Q=p.callback;if(typeof Q=="function"){p.callback=null,m=p.priorityLevel;var ee=Q(p.expirationTime<=P);P=e.unstable_now(),typeof ee=="function"?p.callback=ee:p===n(u)&&r(u),h(P)}else r(u);p=n(u)}if(p!==null)var Rr=!0;else{var Pt=n(a);Pt!==null&&ho(w,Pt.startTime-P),Rr=!1}return Rr}finally{p=null,m=L,S=!1}}var x=!1,R=null,N=-1,j=5,D=-1;function ze(){return!(e.unstable_now()-D<j)}function Nn(){if(R!==null){var T=e.unstable_now();D=T;var P=!0;try{P=R(!0,T)}finally{P?On():(x=!1,R=null)}}else x=!1}var On;if(typeof f=="function")On=function(){f(Nn)};else if(typeof MessageChannel<"u"){var ou=new MessageChannel,Od=ou.port2;ou.port1.onmessage=Nn,On=function(){Od.postMessage(null)}}else On=function(){k(Nn,0)};function po(T){R=T,x||(x=!0,On())}function ho(T,P){N=k(function(){T(e.unstable_now())},P)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(T){T.callback=null},e.unstable_continueExecution=function(){g||S||(g=!0,po(_))},e.unstable_forceFrameRate=function(T){0>T||125<T?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):j=0<T?Math.floor(1e3/T):5},e.unstable_getCurrentPriorityLevel=function(){return m},e.unstable_getFirstCallbackNode=function(){return n(u)},e.unstable_next=function(T){switch(m){case 1:case 2:case 3:var P=3;break;default:P=m}var L=m;m=P;try{return T()}finally{m=L}},e.unstable_pauseExecution=function(){},e.unstable_requestPaint=function(){},e.unstable_runWithPriority=function(T,P){switch(T){case 1:case 2:case 3:case 4:case 5:break;default:T=3}var L=m;m=T;try{return P()}finally{m=L}},e.unstable_scheduleCallback=function(T,P,L){var Q=e.unstable_now();switch(typeof L=="object"&&L!==null?(L=L.delay,L=typeof L=="number"&&0<L?Q+L:Q):L=Q,T){case 1:var ee=-1;break;case 2:ee=250;break;case 5:ee=1073741823;break;case 4:ee=1e4;break;default:ee=5e3}return ee=L+ee,T={id:c++,callback:P,priorityLevel:T,startTime:L,expirationTime:ee,sortIndex:-1},L>Q?(T.sortIndex=L,t(a,T),n(u)===null&&T===n(a)&&(v?(d(N),N=-1):v=!0,ho(w,L-Q))):(T.sortIndex=ee,t(u,T),g||S||(g=!0,po(_))),T},e.unstable_shouldYield=ze,e.unstable_wrapCallback=function(T){var P=m;return function(){var L=m;m=P;try{return T.apply(this,arguments)}finally{m=L}}}})(Qa);qa.exports=Qa;var bd=qa.exports;/**
|
||||
* @license React
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var ep=be,xe=bd;function E(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var Ka=new Set,er={};function Qt(e,t){mn(e,t),mn(e+"Capture",t)}function mn(e,t){for(er[e]=t,e=0;e<t.length;e++)Ka.add(t[e])}var it=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Jo=Object.prototype.hasOwnProperty,tp=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,au={},cu={};function np(e){return Jo.call(cu,e)?!0:Jo.call(au,e)?!1:tp.test(e)?cu[e]=!0:(au[e]=!0,!1)}function rp(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function ip(e,t,n,r){if(t===null||typeof t>"u"||rp(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function he(e,t,n,r,i,o,s){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=i,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=o,this.removeEmptyString=s}var oe={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){oe[e]=new he(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];oe[t]=new he(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){oe[e]=new he(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){oe[e]=new he(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){oe[e]=new he(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){oe[e]=new he(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){oe[e]=new he(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){oe[e]=new he(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){oe[e]=new he(e,5,!1,e.toLowerCase(),null,!1,!1)});var il=/[\-:]([a-z])/g;function ol(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(il,ol);oe[t]=new he(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(il,ol);oe[t]=new he(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(il,ol);oe[t]=new he(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){oe[e]=new he(e,1,!1,e.toLowerCase(),null,!1,!1)});oe.xlinkHref=new he("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){oe[e]=new he(e,1,!1,e.toLowerCase(),null,!0,!0)});function sl(e,t,n,r){var i=oe.hasOwnProperty(t)?oe[t]:null;(i!==null?i.type!==0:r||!(2<t.length)||t[0]!=="o"&&t[0]!==
Line truncated
|
||||
`+go+e}var vo=!1;function wo(e,t){if(!e||vo)return"";vo=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(t,[])}catch(a){var r=a}Reflect.construct(e,[],t)}else{try{t.call()}catch(a){r=a}e.call(t.prototype)}else{try{throw Error()}catch(a){r=a}e()}}catch(a){if(a&&r&&typeof a.stack=="string"){for(var i=a.stack.split(`
|
||||
`),o=r.stack.split(`
|
||||
`),s=i.length-1,l=o.length-1;1<=s&&0<=l&&i[s]!==o[l];)l--;for(;1<=s&&0<=l;s--,l--)if(i[s]!==o[l]){if(s!==1||l!==1)do if(s--,l--,0>l||i[s]!==o[l]){var u=`
|
||||
`+i[s].replace(" at new "," at ");return e.displayName&&u.includes("<anonymous>")&&(u=u.replace("<anonymous>",e.displayName)),u}while(1<=s&&0<=l);break}}}finally{vo=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?jn(e):""}function op(e){switch(e.tag){case 5:return jn(e.type);case 16:return jn("Lazy");case 13:return jn("Suspense");case 19:return jn("SuspenseList");case 0:case 2:case 15:return e=wo(e.type,!1),e;case 11:return e=wo(e.type.render,!1),e;case 1:return e=wo(e.type,!0),e;default:return""}}function es(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Jt:return"Fragment";case Yt:return"Portal";case Go:return"Profiler";case ll:return"StrictMode";case Zo:return"Suspense";case bo:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Ya:return(e.displayName||"Context")+".Consumer";case Xa:return(e._context.displayName||"Context")+".Provider";case ul:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case al:return t=e.displayName||null,t!==null?t:es(e.type)||"Memo";case ct:t=e._payload,e=e._init;try{return es(e(t))}catch{}}return null}function sp(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return es(t);case 8:return t===ll?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function Ct(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function Ga(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function lp(e){var t=Ga(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var i=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return i.call(this)},set:function(s){r=""+s,o.call(this,s)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(s){r=""+s},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function Pr(e){e._valueTracker||(e._valueTracker=lp(e))}function Za(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=Ga(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function hi(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function ts(e,t){var n=t.checked;return W({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function du(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=Ct(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function ba(e,t){t=t.checked,t!=null&&sl(e,"checked",t,!1)}function ns(e,t){ba(e,t);var n=Ct(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?rs(e,t.type,n):t.hasOwnProperty("defaultValue")&&rs(e,t.type,Ct(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function pu(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function rs(e,t,n){(t!=="number"||hi(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var $n=Array.isArray;function un(e,t,n,r){if(e=e.options,t){t={};for(var i=0;i<n.length;i++)t["$"+n[i]]=!0;for(n=0;n<e.length;n++)i=t.hasOwnProperty("$"+e[n].value),e[n].selected!==i&&(e[n].selected=i),i&&r&&(e[n].defaultSelected=!0)}else{for(n=""+Ct(n),t=null,i=0;i<e.length;i++){if(e[i].value===n){e[i].selected=!0,r&&(e[i].defaultSelected=!0);return}t!==null||e[i].disabled||(t=e[i])}t!==null&&(t.selected=!0)}}function is(e,t){if(t.dang
Line truncated
|
||||
`).replace(gh,"")}function Ir(e,t,n){if(t=Bu(t),Bu(e)!==t&&n)throw Error(E(425))}function ki(){}var gs=null,vs=null;function ws(e,t){return e==="textarea"||e==="noscript"||typeof t.children=="string"||typeof t.children=="number"||typeof t.dangerouslySetInnerHTML=="object"&&t.dangerouslySetInnerHTML!==null&&t.dangerouslySetInnerHTML.__html!=null}var Ss=typeof setTimeout=="function"?setTimeout:void 0,vh=typeof clearTimeout=="function"?clearTimeout:void 0,Uu=typeof Promise=="function"?Promise:void 0,wh=typeof queueMicrotask=="function"?queueMicrotask:typeof Uu<"u"?function(e){return Uu.resolve(null).then(e).catch(Sh)}:Ss;function Sh(e){setTimeout(function(){throw e})}function Ao(e,t){var n=t,r=0;do{var i=n.nextSibling;if(e.removeChild(n),i&&i.nodeType===8)if(n=i.data,n==="/$"){if(r===0){e.removeChild(i),or(t);return}r--}else n!=="$"&&n!=="$?"&&n!=="$!"||r++;n=i}while(n);or(t)}function wt(e){for(;e!=null;e=e.nextSibling){var t=e.nodeType;if(t===1||t===3)break;if(t===8){if(t=e.data,t==="$"||t==="$!"||t==="$?")break;if(t==="/$")return null}}return e}function Iu(e){e=e.previousSibling;for(var t=0;e;){if(e.nodeType===8){var n=e.data;if(n==="$"||n==="$!"||n==="$?"){if(t===0)return e;t--}else n==="/$"&&t++}e=e.previousSibling}return null}var xn=Math.random().toString(36).slice(2),Xe="__reactFiber$"+xn,cr="__reactProps$"+xn,ot="__reactContainer$"+xn,Es="__reactEvents$"+xn,Eh="__reactListeners$"+xn,kh="__reactHandles$"+xn;function zt(e){var t=e[Xe];if(t)return t;for(var n=e.parentNode;n;){if(t=n[ot]||n[Xe]){if(n=t.alternate,t.child!==null||n!==null&&n.child!==null)for(e=Iu(e);e!==null;){if(n=e[Xe])return n;e=Iu(e)}return t}e=n,n=e.parentNode}return null}function Er(e){return e=e[Xe]||e[ot],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function en(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(E(33))}function Qi(e){return e[cr]||null}var ks=[],tn=-1;function Nt(e){return{current:e}}function M(e){0>tn||(e.current=ks[tn],ks[tn]=null,tn--)}function U(e,t){tn++,ks[tn]=e.current,e.current=t}var Rt={},ce=Nt(Rt),ge=Nt(!1),jt=Rt;function yn(e,t){var n=e.type.contextTypes;if(!n)return Rt;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var i={},o;for(o in n)i[o]=t[o];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=i),i}function ve(e){return e=e.childContextTypes,e!=null}function _i(){M(ge),M(ce)}function Mu(e,t,n){if(ce.current!==Rt)throw Error(E(168));U(ce,t),U(ge,n)}function $c(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var i in r)if(!(i in t))throw Error(E(108,sp(e)||"Unknown",i));return W({},n,r)}function xi(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Rt,jt=ce.current,U(ce,e),U(ge,ge.current),!0}function ju(e,t,n){var r=e.stateNode;if(!r)throw Error(E(169));n?(e=$c(e,t,jt),r.__reactInternalMemoizedMergedChildContext=e,M(ge),M(ce),U(ce,e)):M(ge),U(ge,n)}var et=null,Ki=!1,Do=!1;function Vc(e){et===null?et=[e]:et.push(e)}function _h(e){Ki=!0,Vc(e)}function Ot(){if(!Do&&et!==null){Do=!0;var e=0,t=B;try{var n=et;for(B=1;e<n.length;e++){var r=n[e];do r=r(!0);while(r!==null)}et=null,Ki=!1}catch(i){throw et!==null&&(et=et.slice(e+1)),pc(fl,Ot),i}finally{B=t,Do=!1}}return null}var nn=[],rn=0,Ci=null,Ri=0,Te=[],Ne=0,$t=null,tt=1,nt="";function At(e,t){nn[rn++]=Ri,nn[rn++]=Ci,Ci=e,Ri=t}function Hc(e,t,n){Te[Ne++]=tt,Te[Ne++]=nt,Te[Ne++]=$t,$t=e;var r=tt;e=nt;var i=32-je(r)-1;r&=~(1<<i),n+=1;var o=32-je(t)+i;if(30<o){var s=i-i%5;o=(r&(1<<s)-1).toString(32),r>>=s,i-=s,tt=1<<32-je(t)+i|n<<i|r,nt=o+e}else tt=1<<o|n<<i|r,nt=e}function Sl(e){e.return!==null&&(At(e,1),Hc(e,1,0))}function El(e){for(;e===Ci;)Ci=nn[--rn],nn[rn]=null,Ri=nn[--rn],nn[rn]=null;for(;e===$t;)$t=Te[--Ne],Te[Ne]=null,nt=Te[--Ne],Te[Ne]=null,tt=Te[--Ne],Te[Ne]=null}var _e=null,ke=null,$=!1,Me=null;function Wc(e,t){var n=Pe(5,null,null,0);n.elementType="DELETED",n.stateNode=t,n.return=e,t=e.deletions,t===null?(e.deletions=[n],e.flags|=16):t.push(n)}function $u(e,t){switch(e.tag){case 5:var n=e.type;return t=t.nodeType!==1||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t,t!==null?(e.stateNode=t,_e=e,ke=wt(t.firstChild),!0):!1;case 6:return t=e.pendingProps===""||t.nodeType!==3?null:t,t!==null?(e.stateNode=t,_e=e,ke=null,!0):!1;case 13:return t=t.nodeType!==8?null:t,t!==null?(n=$t!==null?{id:tt,overflow:nt}:null,e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},n=Pe(18,null,null,0),n.stateNode=t,n.return=e,e.child=n,_e=e,ke=null,!0):!1;default:return!1}}function _s(e){return(e.mode&1)!==0&&(e.flags&128)===0}function xs(e){if($){var t=ke;if(t){var n=t;if(!$u(e,t)){if(_s(e))throw Error(E(418));t=wt(n.nextSibling);var r=_e;t&&$u(e,t)?Wc(r,n):(e.flags=e.flags&-4097|2,$=!1,_e=e)}}else{if(_s(e))throw Error(E(418));e.flags=e.flags&-4097|2,$=!1,_e=e}}}function Vu(e){for(e=e.return;e!==null&&e.t
Line truncated
|
||||
Error generating stack: `+o.message+`
|
||||
`+o.stack}return{value:e,source:t,stack:i,digest:null}}function Io(e,t,n){return{value:e,source:null,stack:n??null,digest:t??null}}function Ns(e,t){try{console.error(t.value)}catch(n){setTimeout(function(){throw n})}}var Ah=typeof WeakMap=="function"?WeakMap:Map;function vf(e,t,n){n=rt(-1,n),n.tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){zi||(zi=!0,Is=r),Ns(e,t)},n}function wf(e,t,n){n=rt(-1,n),n.tag=3;var r=e.type.getDerivedStateFromError;if(typeof r=="function"){var i=t.value;n.payload=function(){return r(i)},n.callback=function(){Ns(e,t)}}var o=e.stateNode;return o!==null&&typeof o.componentDidCatch=="function"&&(n.callback=function(){Ns(e,t),typeof r!="function"&&(Et===null?Et=new Set([this]):Et.add(this));var s=t.stack;this.componentDidCatch(t.value,{componentStack:s!==null?s:""})}),n}function Ju(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Ah;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(i.add(n),e=Qh.bind(null,e,t,n),t.then(e,e))}function Gu(e){do{var t;if((t=e.tag===13)&&(t=e.memoizedState,t=t!==null?t.dehydrated!==null:!0),t)return e;e=e.return}while(e!==null);return null}function Zu(e,t,n,r,i){return e.mode&1?(e.flags|=65536,e.lanes=i,e):(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,n.tag===1&&(n.alternate===null?n.tag=17:(t=rt(-1,1),t.tag=2,St(n,t,1))),n.lanes|=1),e)}var Dh=ut.ReactCurrentOwner,ye=!1;function fe(e,t,n,r){t.child=e===null?Kc(t,null,n,r):vn(t,e.child,n,r)}function bu(e,t,n,r,i){n=n.render;var o=t.ref;return dn(t,i),r=Al(e,t,n,r,o,i),n=Dl(),e!==null&&!ye?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,lt(e,t,i)):($&&n&&Sl(t),t.flags|=1,fe(e,t,r,i),t.child)}function ea(e,t,n,r,i){if(e===null){var o=n.type;return typeof o=="function"&&!Hl(o)&&o.defaultProps===void 0&&n.compare===null&&n.defaultProps===void 0?(t.tag=15,t.type=o,Sf(e,t,o,r,i)):(e=ii(n.type,null,r,t,t.mode,i),e.ref=t.ref,e.return=t,t.child=e)}if(o=e.child,!(e.lanes&i)){var s=o.memoizedProps;if(n=n.compare,n=n!==null?n:lr,n(s,r)&&e.ref===t.ref)return lt(e,t,i)}return t.flags|=1,e=_t(o,r),e.ref=t.ref,e.return=t,t.child=e}function Sf(e,t,n,r,i){if(e!==null){var o=e.memoizedProps;if(lr(o,r)&&e.ref===t.ref)if(ye=!1,t.pendingProps=r=o,(e.lanes&i)!==0)e.flags&131072&&(ye=!0);else return t.lanes=e.lanes,lt(e,t,i)}return Os(e,t,n,r,i)}function Ef(e,t,n){var r=t.pendingProps,i=r.children,o=e!==null?e.memoizedState:null;if(r.mode==="hidden")if(!(t.mode&1))t.memoizedState={baseLanes:0,cachePool:null,transitions:null},U(ln,Ee),Ee|=n;else{if(!(n&1073741824))return e=o!==null?o.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,U(ln,Ee),Ee|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=o!==null?o.baseLanes:n,U(ln,Ee),Ee|=r}else o!==null?(r=o.baseLanes|n,t.memoizedState=null):r=n,U(ln,Ee),Ee|=r;return fe(e,t,i,n),t.child}function kf(e,t){var n=t.ref;(e===null&&n!==null||e!==null&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Os(e,t,n,r,i){var o=ve(n)?jt:ce.current;return o=yn(t,o),dn(t,i),n=Al(e,t,n,r,o,i),r=Dl(),e!==null&&!ye?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,lt(e,t,i)):($&&r&&Sl(t),t.flags|=1,fe(e,t,n,i),t.child)}function ta(e,t,n,r,i){if(ve(n)){var o=!0;xi(t)}else o=!1;if(dn(t,i),t.stateNode===null)ti(e,t),gf(t,n,r),Ts(t,n,r,i),r=!0;else if(e===null){var s=t.stateNode,l=t.memoizedProps;s.props=l;var u=s.context,a=n.contextType;typeof a=="object"&&a!==null?a=Ae(a):(a=ve(n)?jt:ce.current,a=yn(t,a));var c=n.getDerivedStateFromProps,p=typeof c=="function"||typeof s.getSnapshotBeforeUpdate=="function";p||typeof s.UNSAFE_componentWillReceiveProps!="function"&&typeof s.componentWillReceiveProps!="function"||(l!==r||u!==a)&&Yu(t,s,r,a),ft=!1;var m=t.memoizedState;s.state=m,Oi(t,r,s,i),u=t.memoizedState,l!==r||m!==u||ge.current||ft?(typeof c=="function"&&(Rs(t,n,c,r),u=t.memoizedState),(l=ft||Xu(t,n,l,r,m,u,a))?(p||typeof s.UNSAFE_componentWillMount!="function"&&typeof s.componentWillMount!="function"||(typeof s.componentWillMount=="function"&&s.componentWillMount(),typeof s.UNSAFE_componentWillMount=="function"&&s.UNSAFE_componentWillMount()),typeof s.componentDidMount=="function"&&(t.flags|=4194308)):(typeof s.componentDidMount=="function"&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=u),s.props=r,s.state=u,s.context=a,r=l):(typeof s.componentDidMount=="function"&&(t.flags|=4194308),r=!1)}else{s=t.stateNode,Yc(e,t),l=t.memoizedProps,a=t.type===t.elementType?l:Be(t.type,l),s.props=a,p=t.pendingProps,m=s.context,u=n.contextType,typeof u=="object"&&u!==null?u=Ae(u):(u=ve(n)?jt:ce.current,u=yn(t,u));var S=n.getDerivedStateFromProps;(c=typeof S=="function"||typeof s.getSnapshotBeforeUpdate=="function")||typeof s.UNSAFE_componentWillReceiveProps!="function"&&typeof s.componentWillReceiveProps!="function"||(l!==p||m!==u)&&Yu(t,s,r,u),ft=!1,m=t.memoizedState,s.state=m,Oi(t,r,s,i);var g=t.memoizedState;l
Line truncated
|
||||
`).forEach(function(s){i=s.indexOf(":"),n=s.substring(0,i).trim().toLowerCase(),r=s.substring(i+1).trim(),!(!n||t[n]&&sy[n])&&(n==="set-cookie"?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)}),t},wa=Symbol("internals");function In(e){return e&&String(e).trim().toLowerCase()}function si(e){return e===!1||e==null?e:y.isArray(e)?e.map(si):String(e)}function uy(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}const ay=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function Vo(e,t,n,r,i){if(y.isFunction(r))return r.call(this,t,n);if(i&&(t=n),!!y.isString(t)){if(y.isString(r))return t.indexOf(r)!==-1;if(y.isRegExp(r))return r.test(t)}}function cy(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,r)=>n.toUpperCase()+r)}function fy(e,t){const n=y.toCamelCase(" "+t);["get","set","has"].forEach(r=>{Object.defineProperty(e,r+n,{value:function(i,o,s){return this[r].call(this,t,i,o,s)},configurable:!0})})}class lo{constructor(t){t&&this.set(t)}set(t,n,r){const i=this;function o(l,u,a){const c=In(u);if(!c)throw new Error("header name must be a non-empty string");const p=y.findKey(i,c);(!p||i[p]===void 0||a===!0||a===void 0&&i[p]!==!1)&&(i[p||u]=si(l))}const s=(l,u)=>y.forEach(l,(a,c)=>o(a,c,u));if(y.isPlainObject(t)||t instanceof this.constructor)s(t,n);else if(y.isString(t)&&(t=t.trim())&&!ay(t))s(ly(t),n);else if(y.isObject(t)&&y.isIterable(t)){let l={},u,a;for(const c of t){if(!y.isArray(c))throw TypeError("Object iterator must return a key-value pair");l[a=c[0]]=(u=l[a])?y.isArray(u)?[...u,c[1]]:[u,c[1]]:c[1]}s(l,n)}else t!=null&&o(n,t,r);return this}get(t,n){if(t=In(t),t){const r=y.findKey(this,t);if(r){const i=this[r];if(!n)return i;if(n===!0)return uy(i);if(y.isFunction(n))return n.call(this,i,r);if(y.isRegExp(n))return n.exec(i);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=In(t),t){const r=y.findKey(this,t);return!!(r&&this[r]!==void 0&&(!n||Vo(this,this[r],r,n)))}return!1}delete(t,n){const r=this;let i=!1;function o(s){if(s=In(s),s){const l=y.findKey(r,s);l&&(!n||Vo(r,r[l],l,n))&&(delete r[l],i=!0)}}return y.isArray(t)?t.forEach(o):o(t),i}clear(t){const n=Object.keys(this);let r=n.length,i=!1;for(;r--;){const o=n[r];(!t||Vo(this,this[o],o,t,!0))&&(delete this[o],i=!0)}return i}normalize(t){const n=this,r={};return y.forEach(this,(i,o)=>{const s=y.findKey(r,o);if(s){n[s]=si(i),delete n[o];return}const l=t?cy(o):String(o).trim();l!==o&&delete n[o],n[l]=si(i),r[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return y.forEach(this,(r,i)=>{r!=null&&r!==!1&&(n[i]=t&&y.isArray(r)?r.join(", "):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(`
|
||||
`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const r=new this(t);return n.forEach(i=>r.set(i)),r}static accessor(t){const r=(this[wa]=this[wa]={accessors:{}}).accessors,i=this.prototype;function o(s){const l=In(s);r[l]||(fy(i,s),r[l]=!0)}return y.isArray(t)?t.forEach(o):o(t),this}}lo.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);y.reduceDescriptors(lo.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(r){this[n]=r}}});y.freezeMethods(lo);const Ve=lo;function Ho(e,t){const n=this||Zl,r=t||n,i=Ve.from(r.headers);let o=r.data;return y.forEach(e,function(l){o=l.call(n,o,i.normalize(),t?t.status:void 0)}),i.normalize(),o}function ld(e){return!!(e&&e.__CANCEL__)}function Rn(e,t,n){O.call(this,e??"canceled",O.ERR_CANCELED,t,n),this.name="CanceledError"}y.inherits(Rn,O,{__CANCEL__:!0});function ud(e,t,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?e(n):t(new O("Request failed with status code "+n.status,[O.ERR_BAD_REQUEST,O.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function dy(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function py(e,t){e=e||10;const n=new Array(e),r=new Array(e);let i=0,o=0,s;return t=t!==void 0?t:1e3,function(u){const a=Date.now(),c=r[o];s||(s=a),n[i]=u,r[i]=a;let p=o,m=0;for(;p!==i;)m+=n[p++],p=p%e;if(i=(i+1)%e,i===o&&(o=(o+1)%e),a-s<t)return;const S=c&&a-c;return S?Math.round(m*1e3/S):void 0}}function hy(e,t){let n=0,r=1e3/t,i,o;const s=(a,c=Date.now())=>{n=c,i=null,o&&(clearTimeout(o),o=null),e(...a)};return[(...a)=>{const c=Date.now(),p=c-n;p>=r?s(a,c):(i=a,o||(o=setTimeout(()=>{o=null,s(i)},r-p)))},()=>i&&s(i)]}const Ii=(e,t,n=3)=>{let r=0;const i=py(50,250);return hy(o=>{const s=o.loaded,l=o.lengthComputable?o.total:void 0,u=s-r,a=i(u),c=s<=l;r=s;const p={loaded:s,total:l,progress:l?s/l:void 0,bytes:u,rate:a||void 0,estimated:a&&l&&c?(l-s)/a:void 0,event:o,lengthComputable:l!=null,[t?"download":"upload"]:!0};e(p)},n)},Sa=(e,t)=>{const n=e!=null;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},Ea=e=>(...t)=>y.asap(()=>e(...t)),my=ae.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,ae.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(ae.origin),ae.navigator&&/(msie|trident)/i.test(ae.navigator.userAgent)):()=>!0,yy=ae.hasStandardBrowserEnv?{write(e,t,n,r,i,o){const s=[e+"="+encodeURIComponent(t)];y.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),y.isString(r)&&s.push("path="+r),y.isString(i)&&s.push("domain="+i),o===!0&&s.push("secure"),document.cookie=s.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function gy(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function vy(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function ad(e,t,n){let r=!gy(t);return e&&(r||n==!1)?vy(e,t):t}const ka=e=>e instanceof Ve?{...e}:e;function qt(e,t){t=t||{};const n={};function r(a,c,p,m){return y.isPlainObject(a)&&y.isPlainObject(c)?y.merge.call({caseless:m},a,c):y.isPlainObject(c)?y.merge({},c):y.isArray(c)?c.slice():c}function i(a,c,p,m){if(y.isUndefined(c)){if(!y.isUndefined(a))return r(void 0,a,p,m)}else return r(a,c,p,m)}function o(a,c){if(!y.isUndefined(c))return r(void 0,c)}function s(a,c){if(y.isUndefined(c)){if(!y.isUndefined(a))return r(void 0,a)}else return r(void 0,c)}function l(a,c,p){if(p in t)return r(a,c);if(p in e)return r(void 0,a)}const u={url:o,method:o,data:o,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,withXSRFToken:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:l,headers:(a,c,p)=>i(ka(a),ka(c),p,!0)};return y.forEach(Object.keys({...e,...t}),function(c){const p=u[c]||i,m=p(e[c],t[c],c);y.isUndefined(m)&&p!==l||(n[c]=m)}),n}const cd=e=>{const t=qt({},e);let{data:n,withXSRFToken:r,xsrfHeaderName:i,xsrfCookieName:o,headers:s,auth:l}=t;t.headers=s=Ve.from(s),t.url=id(ad(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),l&&s.set("Authorization","Basic "+btoa((l.username||"")+":"+(l.password?unescape(encodeURIComponent(l.password)):"")));let u;if(y.isFormData(n)){if(ae.hasStandardBrowserEnv||ae.hasStandardBrowserWebWorkerEnv)s.setContentType(void 0);else if((u=s.getContentType())!==!1){const[a,...c]=u?u.split(";").map(p=>p.trim()).filter(Boolean):[];s.setContentType([a||"multipart/form-data",...c].join("; "))}}if(ae.hasStandardBrowserEnv&&(r&&y.isFunction(r)&&(r=r(t)),r||r!==!1&&my(t.url))
Line truncated
|
||||
`+o.map(Ca).join(`
|
||||
`):" "+Ca(o[0]):"as no adapter specified";throw new O("There is no suitable adapter to dispatch the request "+s,"ERR_NOT_SUPPORT")}return r},adapters:Qs};function Wo(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Rn(null,e)}function Ra(e){return Wo(e),e.headers=Ve.from(e.headers),e.data=Ho.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),pd.getAdapter(e.adapter||Zl.adapter)(e).then(function(r){return Wo(e),r.data=Ho.call(e,e.transformResponse,r),r.headers=Ve.from(r.headers),r},function(r){return ld(r)||(Wo(e),r&&r.response&&(r.response.data=Ho.call(e,e.transformResponse,r.response),r.response.headers=Ve.from(r.response.headers))),Promise.reject(r)})}const hd="1.11.0",ao={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{ao[e]=function(r){return typeof r===e||"a"+(t<1?"n ":" ")+e}});const Ta={};ao.transitional=function(t,n,r){function i(o,s){return"[Axios v"+hd+"] Transitional option '"+o+"'"+s+(r?". "+r:"")}return(o,s,l)=>{if(t===!1)throw new O(i(s," has been removed"+(n?" in "+n:"")),O.ERR_DEPRECATED);return n&&!Ta[s]&&(Ta[s]=!0,console.warn(i(s," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,s,l):!0}};ao.spelling=function(t){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${t}`),!0)};function Ay(e,t,n){if(typeof e!="object")throw new O("options must be an object",O.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let i=r.length;for(;i-- >0;){const o=r[i],s=t[o];if(s){const l=e[o],u=l===void 0||s(l,o,e);if(u!==!0)throw new O("option "+o+" must be "+u,O.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new O("Unknown option "+o,O.ERR_BAD_OPTION)}}const li={assertOptions:Ay,validators:ao},Qe=li.validators;class ji{constructor(t){this.defaults=t||{},this.interceptors={request:new va,response:new va}}async request(t,n){try{return await this._request(t,n)}catch(r){if(r instanceof Error){let i={};Error.captureStackTrace?Error.captureStackTrace(i):i=new Error;const o=i.stack?i.stack.replace(/^.+\n/,""):"";try{r.stack?o&&!String(r.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(r.stack+=`
|
||||
`+o):r.stack=o}catch{}}throw r}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=qt(this.defaults,n);const{transitional:r,paramsSerializer:i,headers:o}=n;r!==void 0&&li.assertOptions(r,{silentJSONParsing:Qe.transitional(Qe.boolean),forcedJSONParsing:Qe.transitional(Qe.boolean),clarifyTimeoutError:Qe.transitional(Qe.boolean)},!1),i!=null&&(y.isFunction(i)?n.paramsSerializer={serialize:i}:li.assertOptions(i,{encode:Qe.function,serialize:Qe.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),li.assertOptions(n,{baseUrl:Qe.spelling("baseURL"),withXsrfToken:Qe.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let s=o&&y.merge(o.common,o[n.method]);o&&y.forEach(["delete","get","head","post","put","patch","common"],g=>{delete o[g]}),n.headers=Ve.concat(s,o);const l=[];let u=!0;this.interceptors.request.forEach(function(v){typeof v.runWhen=="function"&&v.runWhen(n)===!1||(u=u&&v.synchronous,l.unshift(v.fulfilled,v.rejected))});const a=[];this.interceptors.response.forEach(function(v){a.push(v.fulfilled,v.rejected)});let c,p=0,m;if(!u){const g=[Ra.bind(this),void 0];for(g.unshift(...l),g.push(...a),m=g.length,c=Promise.resolve(n);p<m;)c=c.then(g[p++],g[p++]);return c}m=l.length;let S=n;for(p=0;p<m;){const g=l[p++],v=l[p++];try{S=g(S)}catch(k){v.call(this,k);break}}try{c=Ra.call(this,S)}catch(g){return Promise.reject(g)}for(p=0,m=a.length;p<m;)c=c.then(a[p++],a[p++]);return c}getUri(t){t=qt(this.defaults,t);const n=ad(t.baseURL,t.url,t.allowAbsoluteUrls);return id(n,t.params,t.paramsSerializer)}}y.forEach(["delete","get","head","options"],function(t){ji.prototype[t]=function(n,r){return this.request(qt(r||{},{method:t,url:n,data:(r||{}).data}))}});y.forEach(["post","put","patch"],function(t){function n(r){return function(o,s,l){return this.request(qt(l||{},{method:t,headers:r?{"Content-Type":"multipart/form-data"}:{},url:o,data:s}))}}ji.prototype[t]=n(),ji.prototype[t+"Form"]=n(!0)});const ui=ji;class bl{constructor(t){if(typeof t!="function")throw new TypeError("executor must be a function.");let n;this.promise=new Promise(function(o){n=o});const r=this;this.promise.then(i=>{if(!r._listeners)return;let o=r._listeners.length;for(;o-- >0;)r._listeners[o](i);r._listeners=null}),this.promise.then=i=>{let o;const s=new Promise(l=>{r.subscribe(l),o=l}).then(i);return s.cancel=function(){r.unsubscribe(o)},s},t(function(o,s,l){r.reason||(r.reason=new Rn(o,s,l),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=r=>{t.abort(r)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new bl(function(i){t=i}),cancel:t}}}const Dy=bl;function zy(e){return function(n){return e.apply(null,n)}}function Fy(e){return y.isObject(e)&&e.isAxiosError===!0}const Ks={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ks).forEach(([e,t])=>{Ks[t]=e});const By=Ks;function md(e){const t=new ui(e),n=Qf(ui.prototype.request,t);return y.extend(n,ui.prototype,t,{allOwnKeys:!0}),y.extend(n,t,null,{allOwnKeys:!0}),n.create=function(i){return md(qt(e,i))},n}const J=md(Zl);J.Axios=ui;J.CanceledError=Rn;J.CancelToken=Dy;J.isCancel=ld;J.VERSION=hd;J.toFormData=so;J.AxiosError=O;J.Cancel=J.CanceledError;J.all=function(t){return Promise.all(t)};J.spread=zy;J.isAxiosError=Fy;J.mergeConfig=qt;J.AxiosHeaders=Ve;J.formToJSON=e=>sd(y.isHTMLForm(e)?new FormData(e):e);J.getAdapter=pd.getAdapter;J.HttpStatusCode=By;J.default=J
Line truncated
|
||||
${p?"bg-gray-700 cursor-not-allowed":"bg-gray-800 hover:bg-gray-700"}`,children:[G.jsxs("div",{className:"flex items-center space-x-4",children:[G.jsx("div",{className:`w-12 h-12 flex items-center justify-center rounded-full
|
||||
${c.updateStatus==="✅"?"bg-green-500":c.updateStatus==="⚠️"?"bg-yellow-500":"bg-red-500"}`}),G.jsxs("div",{children:[G.jsx("p",{className:"text-lg font-semibold text-white",children:c.Name}),G.jsxs("p",{className:"text-sm text-gray-400",children:["ID: ",c.Id]})]})]}),!m&&G.jsx("button",{onClick:()=>a(c.Id),disabled:p,className:`px-5 py-2 rounded-lg font-medium transition
|
||||
${p?"bg-orange-500 cursor-not-allowed":"bg-blue-500 hover:bg-blue-600"}`,children:p?"Redeploying":"Redeploy"})]},c.Id)}),e.length===0&&G.jsx("p",{className:"text-gray-400",children:"Keine Stacks gefunden."})]})}function Lg(){return G.jsxs("div",{className:"min-h-screen bg-gray-900 text-white",children:[G.jsxs("header",{className:"p-6 bg-gray-800 shadow-md",children:[G.jsx("h1",{className:"text-2xl font-bold text-white",children:"StackPulse"}),G.jsx("p",{className:"text-gray-400 mt-1",children:"Verwalte deine Docker Stacks"})]}),G.jsx("main",{className:"p-6",children:G.jsx(Pg,{})})]})}Yo.createRoot(document.getElementById("root")).render(G.jsx(Qd.StrictMode,{children:G.jsx(Lg,{})}));
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 156 KiB |
@@ -1,12 +1,39 @@
|
||||
<!--
|
||||
=========================================================
|
||||
* Material Tailwind Dashboard React - v2.1.0
|
||||
=========================================================
|
||||
* Product Page: https://www.creative-tim.com/product/material-tailwind-dashboard-react
|
||||
* Copyright 2023 Creative Tim (https://www.creative-tim.com)
|
||||
* Licensed under MIT (https://github.com/creativetimofficial/material-tailwind-dashboard-react/blob/main/LICENSE.md)
|
||||
* Coded by Creative Tim
|
||||
=========================================================
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/img/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>StackPulse</title>
|
||||
<title>Material Tailwind Dashboard React | By Creative Tim</title>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"
|
||||
integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
<script defer data-site="YOUR_DOMAIN_HERE" src="https://api.nepcha.com/js/nepcha-analytics.js"></script>
|
||||
|
||||
<script type="module" crossorigin src="/assets/index-a1f09468.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-0842cd3a.css">
|
||||
<!-- Nepcha Analytics (nepcha.com) -->
|
||||
<!-- Nepcha is a easy-to-use web analytics. No cookies and fully compliant with GDPR, CCPA and PECR. -->
|
||||
<script defer data-site="YOUR_DOMAIN_HERE" src="https://api.nepcha.com/js/nepcha-analytics.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-4797da57.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-53559ba1.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
+30
-3
@@ -1,10 +1,37 @@
|
||||
<!--
|
||||
=========================================================
|
||||
* Material Tailwind Dashboard React - v2.1.0
|
||||
=========================================================
|
||||
* Product Page: https://www.creative-tim.com/product/material-tailwind-dashboard-react
|
||||
* Copyright 2023 Creative Tim (https://www.creative-tim.com)
|
||||
* Licensed under MIT (https://github.com/creativetimofficial/material-tailwind-dashboard-react/blob/main/LICENSE.md)
|
||||
* Coded by Creative Tim
|
||||
=========================================================
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/img/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>StackPulse</title>
|
||||
<link rel="stylesheet" href="/src/index.css" />
|
||||
<title>Material Tailwind Dashboard React | By Creative Tim</title>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"
|
||||
integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
<script defer data-site="YOUR_DOMAIN_HERE" src="https://api.nepcha.com/js/nepcha-analytics.js"></script>
|
||||
|
||||
<!-- Nepcha Analytics (nepcha.com) -->
|
||||
<!-- Nepcha is a easy-to-use web analytics. No cookies and fully compliant with GDPR, CCPA and PECR. -->
|
||||
<script defer data-site="YOUR_DOMAIN_HERE" src="https://api.nepcha.com/js/nepcha-analytics.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
},
|
||||
},
|
||||
}
|
||||
Generated
-2887
File diff suppressed because it is too large.
Load diff
+25
-14
@@ -1,23 +1,34 @@
|
||||
{
|
||||
"name": "stackpulse-frontend",
|
||||
"version": "0.1.0",
|
||||
"name": "material-tailwind-dashboard-react",
|
||||
"private": true,
|
||||
"version": "2.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.7.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"socket.io-client": "^4.8.1"
|
||||
},
|
||||
"axios": "1.7.5",
|
||||
"socket.io-client": "4.8.1",
|
||||
"@heroicons/react": "2.0.18",
|
||||
"@material-tailwind/react": "2.1.4",
|
||||
"apexcharts": "3.44.0",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "18.2.0",
|
||||
"react-apexcharts": "1.4.1",
|
||||
"react-dom": "18.2.0",
|
||||
"react-router-dom": "6.17.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"postcss": "^8.5.6",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"vite": "^4.4.9"
|
||||
"@types/react": "18.2.31",
|
||||
"@types/react-dom": "18.2.14",
|
||||
"@vitejs/plugin-react": "4.1.0",
|
||||
"autoprefixer": "10.4.16",
|
||||
"postcss": "8.4.31",
|
||||
"prettier": "3.0.3",
|
||||
"prettier-plugin-tailwindcss": "0.5.6",
|
||||
"tailwindcss": "3.3.4",
|
||||
"vite": "4.5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
tailwindConfig: "./tailwind.config.cjs",
|
||||
plugins: [require("prettier-plugin-tailwindcss")],
|
||||
};
|
||||
+10
-61
@@ -1,65 +1,14 @@
|
||||
import React from "react";
|
||||
import { NavLink, Route, Routes } from "react-router-dom";
|
||||
import Stacks from "./Stacks.jsx";
|
||||
import Logs from "./Logs.jsx";
|
||||
import Maintenance from "./Maintenance.jsx";
|
||||
import logo from "./assets/images/stackpulse.png";
|
||||
import { useMaintenance } from "./context/MaintenanceContext.jsx";
|
||||
|
||||
const navLinkBase =
|
||||
"px-4 py-2 rounded-md font-medium transition-colors duration-150";
|
||||
|
||||
const getNavClass = ({ isActive }) =>
|
||||
`${navLinkBase} ${isActive ? "bg-purple-600 text-white" : "text-gray-300 hover:bg-gray-700"}`;
|
||||
|
||||
export default function App() {
|
||||
const { maintenance, update } = useMaintenance();
|
||||
const maintenanceActive = Boolean(maintenance?.active);
|
||||
const maintenanceLabel = maintenance?.message || (update?.running ? "Portainer-Update läuft" : "Wartungsmodus aktiv");
|
||||
import { Routes, Route, Navigate } from "react-router-dom";
|
||||
import { Dashboard, Auth } from "@/layouts";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-900 text-white">
|
||||
<header className="bg-gray-800 shadow-md">
|
||||
<div className="max-w-6xl mx-auto px-6 py-6">
|
||||
<div className="flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
|
||||
<div className="flex flex-col items-end gap-1">
|
||||
<span className="text-xs text-gray-500">v0.3</span>
|
||||
{maintenanceActive && (
|
||||
<span className="flex items-center gap-1 text-xs text-amber-300">
|
||||
<span className="h-2 w-2 animate-pulse rounded-full bg-amber-400" />
|
||||
{maintenanceLabel}
|
||||
</span>
|
||||
)}
|
||||
<img src={logo} alt="StackPulse" className="h-10 w-auto" />
|
||||
</div>
|
||||
<nav className="flex gap-2 items-end">
|
||||
<NavLink to="/" end className={getNavClass}>
|
||||
Stacks
|
||||
</NavLink>
|
||||
<NavLink to="/maintenance" className={getNavClass}>
|
||||
<span className="flex items-center gap-2">
|
||||
Wartung
|
||||
{maintenanceActive && (
|
||||
<span className="h-2 w-2 animate-pulse rounded-full bg-amber-400" />
|
||||
)}
|
||||
</span>
|
||||
</NavLink>
|
||||
|
||||
<NavLink to="/logs" className={getNavClass}>
|
||||
Logs
|
||||
</NavLink>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main className="max-w-6xl mx-auto px-6 py-6">
|
||||
<Routes>
|
||||
<Route path="/" element={<Stacks />} />
|
||||
<Route path="/maintenance" element={<Maintenance />} />
|
||||
<Route path="/logs" element={<Logs />} />
|
||||
<Route path="*" element={<Stacks />} />
|
||||
</Routes>
|
||||
</main>
|
||||
</div>
|
||||
<Routes>
|
||||
<Route path="/dashboard/*" element={<Dashboard />} />
|
||||
<Route path="/auth/*" element={<Auth />} />
|
||||
<Route path="*" element={<Navigate to="/dashboard/stacks" replace />} />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 156 KiB |
@@ -0,0 +1,166 @@
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||
import axios from "axios";
|
||||
|
||||
const MaintenanceContext = createContext(null);
|
||||
|
||||
const INITIAL_STATE = {
|
||||
maintenance: null,
|
||||
update: null,
|
||||
script: null,
|
||||
ssh: null,
|
||||
loading: true,
|
||||
error: "",
|
||||
lastUpdated: null
|
||||
};
|
||||
|
||||
export default function MaintenanceProvider({ children }) {
|
||||
const [state, setState] = useState(INITIAL_STATE);
|
||||
const pollingRef = useRef(null);
|
||||
const wasRunningRef = useRef(false);
|
||||
|
||||
const applyState = useCallback((partial) => {
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
...partial
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const fetchConfig = useCallback(async () => {
|
||||
applyState({ loading: true, error: "" });
|
||||
try {
|
||||
const response = await axios.get("/api/maintenance/config");
|
||||
const data = response.data ?? {};
|
||||
applyState({
|
||||
maintenance: data.maintenance ?? null,
|
||||
update: data.update ?? null,
|
||||
script: data.script ?? null,
|
||||
ssh: data.ssh ?? null,
|
||||
loading: false,
|
||||
error: "",
|
||||
lastUpdated: new Date()
|
||||
});
|
||||
} catch (err) {
|
||||
const message = err.response?.data?.error || err.message || "Fehler beim Laden der Wartungsdaten";
|
||||
applyState({ loading: false, error: message });
|
||||
}
|
||||
}, [applyState]);
|
||||
|
||||
const refreshUpdateStatus = useCallback(async () => {
|
||||
try {
|
||||
const response = await axios.get("/api/maintenance/update-status");
|
||||
const data = response.data ?? {};
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
maintenance: data.maintenance ?? prev.maintenance,
|
||||
update: data.update ?? prev.update,
|
||||
error: ""
|
||||
}));
|
||||
} catch (err) {
|
||||
const message = err.response?.data?.error || err.message || "Fehler beim Aktualisieren des Wartungsstatus";
|
||||
setState((prev) => ({ ...prev, error: message }));
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
fetchConfig();
|
||||
}, [fetchConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
if (state.update?.running) {
|
||||
refreshUpdateStatus();
|
||||
const intervalId = setInterval(() => {
|
||||
refreshUpdateStatus();
|
||||
}, 5000);
|
||||
pollingRef.current = intervalId;
|
||||
return () => clearInterval(intervalId);
|
||||
}
|
||||
if (pollingRef.current) {
|
||||
clearInterval(pollingRef.current);
|
||||
pollingRef.current = null;
|
||||
}
|
||||
return undefined;
|
||||
}, [state.update?.running, refreshUpdateStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
const currentlyRunning = Boolean(state.update?.running);
|
||||
if (!currentlyRunning && wasRunningRef.current) {
|
||||
fetchConfig();
|
||||
}
|
||||
wasRunningRef.current = currentlyRunning;
|
||||
}, [state.update?.running, fetchConfig]);
|
||||
|
||||
const triggerUpdate = useCallback(async (payload = {}) => {
|
||||
await axios.post("/api/maintenance/portainer-update", payload);
|
||||
await refreshUpdateStatus();
|
||||
}, [refreshUpdateStatus]);
|
||||
|
||||
const saveScript = useCallback(async (script) => {
|
||||
await axios.put("/api/maintenance/update-script", { script });
|
||||
await fetchConfig();
|
||||
}, [fetchConfig]);
|
||||
|
||||
const resetScript = useCallback(async () => {
|
||||
await axios.delete("/api/maintenance/update-script");
|
||||
await fetchConfig();
|
||||
}, [fetchConfig]);
|
||||
|
||||
const saveSshConfig = useCallback(async (config) => {
|
||||
await axios.put("/api/maintenance/ssh-config", config);
|
||||
await fetchConfig();
|
||||
}, [fetchConfig]);
|
||||
|
||||
const deleteSshConfig = useCallback(async () => {
|
||||
await axios.delete("/api/maintenance/ssh-config");
|
||||
await fetchConfig();
|
||||
}, [fetchConfig]);
|
||||
|
||||
const setMaintenanceMode = useCallback(async ({ active, message } = {}) => {
|
||||
const payload = { active: Boolean(active) };
|
||||
if (message !== undefined) {
|
||||
payload.message = message;
|
||||
}
|
||||
|
||||
const response = await axios.post("/api/maintenance/mode", payload);
|
||||
const nextMaintenance = response.data?.maintenance ?? null;
|
||||
applyState({ maintenance: nextMaintenance, error: "" });
|
||||
return nextMaintenance;
|
||||
}, [applyState]);
|
||||
|
||||
const testSshConnection = useCallback(async (config) => {
|
||||
const response = await axios.post("/api/maintenance/test-ssh", config ?? {});
|
||||
return response.data;
|
||||
}, []);
|
||||
|
||||
const value = useMemo(() => ({
|
||||
maintenance: state.maintenance,
|
||||
update: state.update,
|
||||
script: state.script,
|
||||
ssh: state.ssh,
|
||||
loading: state.loading,
|
||||
error: state.error,
|
||||
lastUpdated: state.lastUpdated,
|
||||
refreshConfig: fetchConfig,
|
||||
refreshUpdateStatus,
|
||||
setMaintenanceMode,
|
||||
triggerUpdate,
|
||||
saveScript,
|
||||
resetScript,
|
||||
saveSshConfig,
|
||||
deleteSshConfig,
|
||||
testSshConnection
|
||||
}), [state, fetchConfig, refreshUpdateStatus, setMaintenanceMode, triggerUpdate, saveScript, resetScript, saveSshConfig, deleteSshConfig, testSshConnection]);
|
||||
|
||||
return (
|
||||
<MaintenanceContext.Provider value={value}>
|
||||
{children}
|
||||
</MaintenanceContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useMaintenance() {
|
||||
const context = useContext(MaintenanceContext);
|
||||
if (!context) {
|
||||
throw new Error('useMaintenance must be used within a MaintenanceProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
import React, { createContext, useCallback, useContext, useMemo, useRef, useState } from "react";
|
||||
|
||||
const DEFAULT_PER_PAGE_OPTIONS = [
|
||||
{ value: "10", label: "10" },
|
||||
{ value: "25", label: "25" },
|
||||
{ value: "50", label: "50" },
|
||||
{ value: "100", label: "100" },
|
||||
{ value: "all", label: "Alle" }
|
||||
];
|
||||
|
||||
const DEFAULT_PER_PAGE = "50";
|
||||
|
||||
const PageContext = createContext(null);
|
||||
|
||||
const normalizeNumber = (value, fallback) => {
|
||||
const numeric = Number(value);
|
||||
if (Number.isFinite(numeric) && numeric > 0) {
|
||||
return numeric;
|
||||
}
|
||||
const fallbackNumeric = Number(fallback);
|
||||
if (Number.isFinite(fallbackNumeric) && fallbackNumeric > 0) {
|
||||
return fallbackNumeric;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
export function PageProvider({
|
||||
children,
|
||||
initialPage = 1,
|
||||
initialPerPage = DEFAULT_PER_PAGE,
|
||||
perPageOptions = DEFAULT_PER_PAGE_OPTIONS
|
||||
}) {
|
||||
const [page, setPage] = useState(initialPage);
|
||||
const [perPage, setPerPage] = useState(initialPerPage);
|
||||
const [totalItems, setTotalItems] = useState(0);
|
||||
const [visibleItems, setVisibleItems] = useState(0);
|
||||
|
||||
const initialPageRef = useRef(initialPage);
|
||||
const initialPerPageRef = useRef(initialPerPage);
|
||||
|
||||
const validPerPageValues = useMemo(() => new Set(
|
||||
perPageOptions.map((option) => String(option.value))
|
||||
), [perPageOptions]);
|
||||
|
||||
const perPageIsAll = perPage === "all";
|
||||
|
||||
const resolvePerPageNumber = useCallback(() => {
|
||||
if (perPageIsAll) {
|
||||
return null;
|
||||
}
|
||||
return normalizeNumber(perPage, initialPerPage);
|
||||
}, [perPage, perPageIsAll, initialPerPage]);
|
||||
|
||||
const updateTotals = useCallback((total, visible) => {
|
||||
setTotalItems(Math.max(0, Number(total) || 0));
|
||||
setVisibleItems(Math.max(0, Number(visible) || 0));
|
||||
}, []);
|
||||
|
||||
const resetPagination = useCallback(() => {
|
||||
setPage(initialPageRef.current ?? 1);
|
||||
setPerPage(initialPerPageRef.current ?? DEFAULT_PER_PAGE);
|
||||
setTotalItems(0);
|
||||
setVisibleItems(0);
|
||||
}, []);
|
||||
|
||||
const setPerPageValue = useCallback((value, { resetPage = true } = {}) => {
|
||||
if (value === undefined || value === null) return;
|
||||
const nextValue = String(value);
|
||||
if (!validPerPageValues.has(nextValue)) {
|
||||
return;
|
||||
}
|
||||
setPerPage(nextValue);
|
||||
if (resetPage) {
|
||||
setPage(1);
|
||||
}
|
||||
}, [validPerPageValues]);
|
||||
|
||||
const handlePerPageChange = useCallback((eventOrValue) => {
|
||||
const nextValue = typeof eventOrValue === "string"
|
||||
? eventOrValue
|
||||
: eventOrValue?.target?.value;
|
||||
setPerPageValue(nextValue, { resetPage: true });
|
||||
}, [setPerPageValue]);
|
||||
|
||||
const handlePageChange = useCallback((nextPage) => {
|
||||
if (perPageIsAll) return;
|
||||
|
||||
const numericPage = Number(nextPage);
|
||||
if (!Number.isFinite(numericPage) || numericPage < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const perPageNumber = resolvePerPageNumber();
|
||||
if (!perPageNumber) {
|
||||
return;
|
||||
}
|
||||
|
||||
const maxPages = Math.max(1, Math.ceil((totalItems || 0) / perPageNumber));
|
||||
if (numericPage > maxPages) {
|
||||
return;
|
||||
}
|
||||
|
||||
setPage(numericPage);
|
||||
}, [perPageIsAll, resolvePerPageNumber, totalItems]);
|
||||
|
||||
const totalPages = useMemo(() => {
|
||||
if (perPageIsAll) {
|
||||
return 1;
|
||||
}
|
||||
const perPageNumber = resolvePerPageNumber();
|
||||
if (!perPageNumber) {
|
||||
return 1;
|
||||
}
|
||||
return Math.max(1, Math.ceil((totalItems || 0) / perPageNumber));
|
||||
}, [perPageIsAll, resolvePerPageNumber, totalItems]);
|
||||
|
||||
const rangeStart = useMemo(() => {
|
||||
if (!totalItems) {
|
||||
return 0;
|
||||
}
|
||||
if (perPageIsAll) {
|
||||
return 1;
|
||||
}
|
||||
const perPageNumber = resolvePerPageNumber();
|
||||
return (page - 1) * perPageNumber + 1;
|
||||
}, [totalItems, perPageIsAll, resolvePerPageNumber, page]);
|
||||
|
||||
const rangeEnd = useMemo(() => {
|
||||
if (!totalItems) {
|
||||
return 0;
|
||||
}
|
||||
if (perPageIsAll) {
|
||||
return totalItems;
|
||||
}
|
||||
const perPageNumber = resolvePerPageNumber();
|
||||
const estimatedEnd = (page - 1) * perPageNumber + (visibleItems || perPageNumber);
|
||||
return Math.min(totalItems, estimatedEnd);
|
||||
}, [totalItems, perPageIsAll, resolvePerPageNumber, page, visibleItems]);
|
||||
|
||||
const summaryLabel = useMemo(() => {
|
||||
if (!totalItems) {
|
||||
return "Keine Einträge";
|
||||
}
|
||||
if (perPageIsAll) {
|
||||
return `Zeige alle ${totalItems.toLocaleString()} Einträge`;
|
||||
}
|
||||
return `Zeige ${rangeStart.toLocaleString()} – ${rangeEnd.toLocaleString()} von ${totalItems.toLocaleString()} Einträgen`;
|
||||
}, [totalItems, perPageIsAll, rangeStart, rangeEnd]);
|
||||
|
||||
const value = useMemo(() => ({
|
||||
page,
|
||||
perPage,
|
||||
perPageOptions,
|
||||
perPageIsAll,
|
||||
totalItems,
|
||||
visibleItems,
|
||||
totalPages,
|
||||
rangeStart,
|
||||
rangeEnd,
|
||||
summaryLabel,
|
||||
setPage,
|
||||
setPerPage: setPerPageValue,
|
||||
setTotals: updateTotals,
|
||||
setTotalItems,
|
||||
setVisibleItems,
|
||||
handlePageChange,
|
||||
handlePerPageChange,
|
||||
validPerPageValues,
|
||||
resetPagination
|
||||
}), [
|
||||
page,
|
||||
perPage,
|
||||
perPageOptions,
|
||||
perPageIsAll,
|
||||
totalItems,
|
||||
visibleItems,
|
||||
totalPages,
|
||||
rangeStart,
|
||||
rangeEnd,
|
||||
summaryLabel,
|
||||
updateTotals,
|
||||
setPerPageValue,
|
||||
handlePageChange,
|
||||
handlePerPageChange,
|
||||
validPerPageValues,
|
||||
resetPagination
|
||||
]);
|
||||
|
||||
return (
|
||||
<PageContext.Provider value={value}>
|
||||
{children}
|
||||
</PageContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function usePage() {
|
||||
const context = useContext(PageContext);
|
||||
if (!context) {
|
||||
throw new Error("usePage must be used within a PageProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export function PaginationControls({ disabled = false }) {
|
||||
const {
|
||||
summaryLabel,
|
||||
perPageIsAll,
|
||||
page,
|
||||
totalPages,
|
||||
handlePageChange
|
||||
} = usePage();
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<span>{summaryLabel}</span>
|
||||
{!perPageIsAll && (
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={() => handlePageChange(page - 1)}
|
||||
disabled={disabled || page <= 1}
|
||||
className="rounded-md border border-slate-300 p-2.5 text-center text-sm transition-all shadow-sm hover:shadow-lg text-slate-600 hover:text-white hover:bg-slate-800 hover:border-slate-800 focus:text-white focus:bg-slate-800 focus:border-slate-800 active:border-slate-800 active:text-white active:bg-slate-800 disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
type="button"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" className="h-4 w-4">
|
||||
<path d="M11.03 3.97a.75.75 0 0 1 0 1.06l-6.22 6.22H21a.75.75 0 0 1 0 1.5H4.81l6.22 6.22a.75.75 0 1 1-1.06 1.06l-7.5-7.5a.75.75 0 0 1 0-1.06l7.5-7.5a.75.75 0 0 1 1.06 0Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<p className="text-slate-600">
|
||||
Seite <strong className="text-slate-800">{page}</strong> /
|
||||
<strong className="text-slate-800">{totalPages}</strong>
|
||||
</p>
|
||||
<button
|
||||
onClick={() => handlePageChange(page + 1)}
|
||||
disabled={disabled || page >= totalPages}
|
||||
className="rounded-md border border-slate-300 p-2.5 text-center text-sm transition-all shadow-sm hover:shadow-lg text-slate-600 hover:text-white hover:bg-slate-800 hover:border-slate-800 focus:text-white focus:bg-slate-800 focus:border-slate-800 active:border-slate-800 active:text-white active:bg-slate-800 disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
type="button"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" className="h-4 w-4">
|
||||
<path d="M12.97 3.97a.75.75 0 0 1 1.06 0l7.5 7.5a.75.75 0 0 1 0 1.06l-7.5 7.5a.75.75 0 1 1-1.06-1.06l6.22-6.22H3a.75.75 0 0 1 0-1.5h16.19l-6.22-6.22a.75.75 0 0 1 0-1.06Z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const PAGE_DEFAULTS = {
|
||||
perPage: DEFAULT_PER_PAGE,
|
||||
options: DEFAULT_PER_PAGE_OPTIONS
|
||||
};
|
||||
|
||||
export default PageProvider;
|
||||
@@ -4,20 +4,20 @@ const ToastContext = createContext(null);
|
||||
|
||||
const VARIANT_STYLES = {
|
||||
success: {
|
||||
container: "border-green-500/80 bg-green-950/90 text-green-100",
|
||||
accent: "bg-green-400"
|
||||
container: "border-mossGreen-500/80 bg-mossGreen-900/90 text-white",
|
||||
accent: "bg-mossGreen-400"
|
||||
},
|
||||
warning: {
|
||||
container: "border-yellow-500/80 bg-yellow-950/90 text-yellow-100",
|
||||
accent: "bg-yellow-400"
|
||||
container: "border-warmAmberGlow-500/80 bg-warmAmberGlow-900/90 text-white",
|
||||
accent: "bg-warmAmberGlow-400"
|
||||
},
|
||||
error: {
|
||||
container: "border-red-500/80 bg-red-950/90 text-red-100",
|
||||
accent: "bg-red-400"
|
||||
container: "border-sunsetCoral-500/80 bg-sunsetCoral-900/90 text-white",
|
||||
accent: "bg-sunsetCoral-400"
|
||||
},
|
||||
info: {
|
||||
container: "border-sky-500/60 bg-sky-950/90 text-sky-100",
|
||||
accent: "bg-sky-400"
|
||||
container: "border-arcticBlue-500 bg-arcticBlue-900/90 text-white",
|
||||
accent: "bg-arcticBlue-400"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export const MaterialTailwind = React.createContext(null);
|
||||
MaterialTailwind.displayName = "MaterialTailwindContext";
|
||||
|
||||
export function reducer(state, action) {
|
||||
switch (action.type) {
|
||||
case "OPEN_SIDENAV": {
|
||||
return { ...state, openSidenav: action.value };
|
||||
}
|
||||
case "SIDENAV_TYPE": {
|
||||
return { ...state, sidenavType: action.value };
|
||||
}
|
||||
case "SIDENAV_COLOR": {
|
||||
return { ...state, sidenavColor: action.value };
|
||||
}
|
||||
case "TRANSPARENT_NAVBAR": {
|
||||
return { ...state, transparentNavbar: action.value };
|
||||
}
|
||||
case "FIXED_NAVBAR": {
|
||||
return { ...state, fixedNavbar: action.value };
|
||||
}
|
||||
case "OPEN_CONFIGURATOR": {
|
||||
return { ...state, openConfigurator: action.value };
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unhandled action type: ${action.type}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function MaterialTailwindControllerProvider({ children }) {
|
||||
const initialState = {
|
||||
openSidenav: false,
|
||||
sidenavColor: "gray",
|
||||
sidenavType: "white",
|
||||
transparentNavbar: false,
|
||||
fixedNavbar: true,
|
||||
openConfigurator: false,
|
||||
};
|
||||
|
||||
const [controller, dispatch] = React.useReducer(reducer, initialState);
|
||||
const value = React.useMemo(
|
||||
() => [controller, dispatch],
|
||||
[controller, dispatch]
|
||||
);
|
||||
|
||||
return (
|
||||
<MaterialTailwind.Provider value={value}>
|
||||
{children}
|
||||
</MaterialTailwind.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useMaterialTailwindController() {
|
||||
const context = React.useContext(MaterialTailwind);
|
||||
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useMaterialTailwindController should be used inside the MaterialTailwindControllerProvider."
|
||||
);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
MaterialTailwindControllerProvider.displayName = "/src/context/index.jsx";
|
||||
|
||||
MaterialTailwindControllerProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export const setOpenSidenav = (dispatch, value) =>
|
||||
dispatch({ type: "OPEN_SIDENAV", value });
|
||||
export const setSidenavType = (dispatch, value) =>
|
||||
dispatch({ type: "SIDENAV_TYPE", value });
|
||||
export const setSidenavColor = (dispatch, value) =>
|
||||
dispatch({ type: "SIDENAV_COLOR", value });
|
||||
export const setTransparentNavbar = (dispatch, value) =>
|
||||
dispatch({ type: "TRANSPARENT_NAVBAR", value });
|
||||
export const setFixedNavbar = (dispatch, value) =>
|
||||
dispatch({ type: "FIXED_NAVBAR", value });
|
||||
export const setOpenConfigurator = (dispatch, value) =>
|
||||
dispatch({ type: "OPEN_CONFIGURATOR", value });
|
||||
@@ -0,0 +1,61 @@
|
||||
export const chartsConfig = {
|
||||
chart: {
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
title: {
|
||||
show: "",
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
xaxis: {
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
labels: {
|
||||
style: {
|
||||
colors: "#37474f",
|
||||
fontSize: "13px",
|
||||
fontFamily: "inherit",
|
||||
fontWeight: 300,
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
style: {
|
||||
colors: "#37474f",
|
||||
fontSize: "13px",
|
||||
fontFamily: "inherit",
|
||||
fontWeight: 300,
|
||||
},
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
show: true,
|
||||
borderColor: "#dddddd",
|
||||
strokeDashArray: 5,
|
||||
xaxis: {
|
||||
lines: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
padding: {
|
||||
top: 5,
|
||||
right: 20,
|
||||
},
|
||||
},
|
||||
fill: {
|
||||
opacity: 0.8,
|
||||
},
|
||||
tooltip: {
|
||||
theme: "dark",
|
||||
},
|
||||
};
|
||||
|
||||
export default chartsConfig;
|
||||
@@ -0,0 +1 @@
|
||||
export * from "@/configs/charts-config";
|
||||
@@ -0,0 +1,52 @@
|
||||
export const authorsTableData = [
|
||||
{
|
||||
img: "/img/team-2.jpeg",
|
||||
name: "John Michael",
|
||||
email: "john@creative-tim.com",
|
||||
job: ["Manager", "Organization"],
|
||||
online: true,
|
||||
date: "23/04/18",
|
||||
},
|
||||
{
|
||||
img: "/img/team-1.jpeg",
|
||||
name: "Alexa Liras",
|
||||
email: "alexa@creative-tim.com",
|
||||
job: ["Programator", "Developer"],
|
||||
online: false,
|
||||
date: "11/01/19",
|
||||
},
|
||||
{
|
||||
img: "/img/team-4.jpeg",
|
||||
name: "Laurent Perrier",
|
||||
email: "laurent@creative-tim.com",
|
||||
job: ["Executive", "Projects"],
|
||||
online: true,
|
||||
date: "19/09/17",
|
||||
},
|
||||
{
|
||||
img: "/img/team-3.jpeg",
|
||||
name: "Michael Levi",
|
||||
email: "michael@creative-tim.com",
|
||||
job: ["Programator", "Developer"],
|
||||
online: true,
|
||||
date: "24/12/08",
|
||||
},
|
||||
{
|
||||
img: "/img/bruce-mars.jpeg",
|
||||
name: "Bruce Mars",
|
||||
email: "bruce@creative-tim.com",
|
||||
job: ["Manager", "Executive"],
|
||||
online: false,
|
||||
date: "04/10/21",
|
||||
},
|
||||
{
|
||||
img: "/img/team-2.jpeg",
|
||||
name: "Alexander",
|
||||
email: "alexander@creative-tim.com",
|
||||
job: ["Programator", "Developer"],
|
||||
online: false,
|
||||
date: "14/09/20",
|
||||
},
|
||||
];
|
||||
|
||||
export default authorsTableData;
|
||||
@@ -0,0 +1,29 @@
|
||||
export const conversationsData = [
|
||||
{
|
||||
img: "/img/team-1.jpeg",
|
||||
name: "Sophie B.",
|
||||
message: "Hi! I need more information...",
|
||||
},
|
||||
{
|
||||
img: "/img/team-2.jpeg",
|
||||
name: "Alexander",
|
||||
message: "Awesome work, can you...",
|
||||
},
|
||||
{
|
||||
img: "/img/team-3.jpeg",
|
||||
name: "Ivanna",
|
||||
message: "About files I can...",
|
||||
},
|
||||
{
|
||||
img: "/img/team-4.jpeg",
|
||||
name: "Peterson",
|
||||
message: "Have a great afternoon...",
|
||||
},
|
||||
{
|
||||
img: "/img/bruce-mars.jpeg",
|
||||
name: "Bruce Mars",
|
||||
message: "Hi! I need more information...",
|
||||
},
|
||||
];
|
||||
|
||||
export default conversationsData;
|
||||
@@ -0,0 +1,8 @@
|
||||
export * from "@/data/statistics-cards-data";
|
||||
export * from "@/data/statistics-charts-data";
|
||||
export * from "@/data/projects-table-data";
|
||||
export * from "@/data/orders-overview-data";
|
||||
export * from "@/data/platform-settings-data";
|
||||
export * from "@/data/conversations-data";
|
||||
export * from "@/data/projects-data";
|
||||
export * from "@/data/authors-table-data";
|
||||
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
BellIcon,
|
||||
PlusCircleIcon,
|
||||
ShoppingCartIcon,
|
||||
CreditCardIcon,
|
||||
LockOpenIcon,
|
||||
BanknotesIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
|
||||
export const ordersOverviewData = [
|
||||
{
|
||||
icon: BellIcon,
|
||||
color: "text-blue-gray-300",
|
||||
title: "$2400, Design changes",
|
||||
description: "22 DEC 7:20 PM",
|
||||
},
|
||||
{
|
||||
icon: PlusCircleIcon,
|
||||
color: "text-blue-gray-300",
|
||||
title: "New order #1832412",
|
||||
description: "21 DEC 11 PM",
|
||||
},
|
||||
{
|
||||
icon: ShoppingCartIcon,
|
||||
color: "text-blue-gray-300",
|
||||
title: "Server payments for April",
|
||||
description: "21 DEC 9:34 PM",
|
||||
},
|
||||
{
|
||||
icon: CreditCardIcon,
|
||||
color: "text-blue-gray-300",
|
||||
title: "New card added for order #4395133",
|
||||
description: "20 DEC 2:20 AM",
|
||||
},
|
||||
{
|
||||
icon: LockOpenIcon,
|
||||
color: "text-blue-gray-300",
|
||||
title: "Unlock packages for development",
|
||||
description: "18 DEC 4:54 AM",
|
||||
},
|
||||
{
|
||||
icon: BanknotesIcon,
|
||||
color: "text-blue-gray-300",
|
||||
title: "New order #9583120",
|
||||
description: "17 DEC",
|
||||
},
|
||||
];
|
||||
|
||||
export default ordersOverviewData;
|
||||
@@ -0,0 +1,38 @@
|
||||
export const platformSettingsData = [
|
||||
{
|
||||
title: "account",
|
||||
options: [
|
||||
{
|
||||
checked: true,
|
||||
label: "Email me when someone follows me",
|
||||
},
|
||||
{
|
||||
checked: false,
|
||||
label: "Email me when someone answers on my post",
|
||||
},
|
||||
{
|
||||
checked: true,
|
||||
label: "Email me when someone mentions me",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "application",
|
||||
options: [
|
||||
{
|
||||
checked: false,
|
||||
label: "New launches and projects",
|
||||
},
|
||||
{
|
||||
checked: true,
|
||||
label: "Monthly product updates",
|
||||
},
|
||||
{
|
||||
checked: false,
|
||||
label: "Subscribe to newsletter",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default platformSettingsData;
|
||||
@@ -0,0 +1,60 @@
|
||||
export const projectsData = [
|
||||
{
|
||||
img: "/img/home-decor-1.jpeg",
|
||||
title: "Modern",
|
||||
tag: "Project #1",
|
||||
description:
|
||||
"As Uber works through a huge amount of internal management turmoil.",
|
||||
route: "/dashboard/profile",
|
||||
members: [
|
||||
{ img: "/img/team-1.jpeg", name: "Romina Hadid" },
|
||||
{ img: "/img/team-2.jpeg", name: "Ryan Tompson" },
|
||||
{ img: "/img/team-3.jpeg", name: "Jessica Doe" },
|
||||
{ img: "/img/team-4.jpeg", name: "Alexander Smith" },
|
||||
],
|
||||
},
|
||||
{
|
||||
img: "/img/home-decor-2.jpeg",
|
||||
title: "Scandinavian",
|
||||
tag: "Project #2",
|
||||
description:
|
||||
"Music is something that every person has his or her own specific opinion about.",
|
||||
route: "/dashboard/profile",
|
||||
members: [
|
||||
{ img: "/img/team-4.jpeg", name: "Alexander Smith" },
|
||||
{ img: "/img/team-3.jpeg", name: "Jessica Doe" },
|
||||
{ img: "/img/team-2.jpeg", name: "Ryan Tompson" },
|
||||
{ img: "/img/team-1.jpeg", name: "Romina Hadid" },
|
||||
],
|
||||
},
|
||||
{
|
||||
img: "/img/home-decor-3.jpeg",
|
||||
title: "Minimalist",
|
||||
tag: "Project #3",
|
||||
description:
|
||||
"Different people have different taste, and various types of music.",
|
||||
route: "/dashboard/profile",
|
||||
members: [
|
||||
{ img: "/img/team-1.jpeg", name: "Romina Hadid" },
|
||||
{ img: "/img/team-2.jpeg", name: "Ryan Tompson" },
|
||||
{ img: "/img/team-3.jpeg", name: "Jessica Doe" },
|
||||
{ img: "/img/team-4.jpeg", name: "Alexander Smith" },
|
||||
],
|
||||
},
|
||||
{
|
||||
img: "/img/home-decor-4.jpeg",
|
||||
title: "Gothic",
|
||||
tag: "Project #4",
|
||||
description:
|
||||
"Why would anyone pick blue over pink? Pink is obviously a better color.",
|
||||
route: "/dashboard/profile",
|
||||
members: [
|
||||
{ img: "/img/team-4.jpeg", name: "Alexander Smith" },
|
||||
{ img: "/img/team-3.jpeg", name: "Jessica Doe" },
|
||||
{ img: "/img/team-2.jpeg", name: "Ryan Tompson" },
|
||||
{ img: "/img/team-1.jpeg", name: "Romina Hadid" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default projectsData;
|
||||
@@ -0,0 +1,65 @@
|
||||
export const projectsTableData = [
|
||||
{
|
||||
img: "/img/logo-xd.svg",
|
||||
name: "Material XD Version",
|
||||
members: [
|
||||
{ img: "/img/team-1.jpeg", name: "Romina Hadid" },
|
||||
{ img: "/img/team-2.jpeg", name: "Ryan Tompson" },
|
||||
{ img: "/img/team-3.jpeg", name: "Jessica Doe" },
|
||||
{ img: "/img/team-4.jpeg", name: "Alexander Smith" },
|
||||
],
|
||||
budget: "$14,000",
|
||||
completion: 60,
|
||||
},
|
||||
{
|
||||
img: "/img/logo-atlassian.svg",
|
||||
name: "Add Progress Track",
|
||||
members: [
|
||||
{ img: "/img/team-2.jpeg", name: "Ryan Tompson" },
|
||||
{ img: "/img/team-4.jpeg", name: "Alexander Smith" },
|
||||
],
|
||||
budget: "$3,000",
|
||||
completion: 10,
|
||||
},
|
||||
{
|
||||
img: "/img/logo-slack.svg",
|
||||
name: "Fix Platform Errors",
|
||||
members: [
|
||||
{ img: "/img/team-3.jpeg", name: "Jessica Doe" },
|
||||
{ img: "/img/team-1.jpeg", name: "Romina Hadid" },
|
||||
],
|
||||
budget: "Not set",
|
||||
completion: 100,
|
||||
},
|
||||
{
|
||||
img: "/img/logo-spotify.svg",
|
||||
name: "Launch our Mobile App",
|
||||
members: [
|
||||
{ img: "/img/team-4.jpeg", name: "Alexander Smith" },
|
||||
{ img: "/img/team-3.jpeg", name: "Jessica Doe" },
|
||||
{ img: "/img/team-2.jpeg", name: "Ryan Tompson" },
|
||||
{ img: "/img/team-1.jpeg", name: "Romina Hadid" },
|
||||
],
|
||||
budget: "$20,500",
|
||||
completion: 100,
|
||||
},
|
||||
{
|
||||
img: "/img/logo-jira.svg",
|
||||
name: "Add the New Pricing Page",
|
||||
members: [{ img: "/img/team-4.jpeg", name: "Alexander Smith" }],
|
||||
budget: "$500",
|
||||
completion: 25,
|
||||
},
|
||||
{
|
||||
img: "/img/logo-invision.svg",
|
||||
name: "Redesign New Online Shop",
|
||||
members: [
|
||||
{ img: "/img/team-1.jpeg", name: "Romina Hadid" },
|
||||
{ img: "/img/team-4.jpeg", name: "Alexander Smith" },
|
||||
],
|
||||
budget: "$2,000",
|
||||
completion: 40,
|
||||
},
|
||||
];
|
||||
|
||||
export default projectsTableData;
|
||||
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
BanknotesIcon,
|
||||
UserPlusIcon,
|
||||
UsersIcon,
|
||||
ChartBarIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
|
||||
export const statisticsCardsData = [
|
||||
{
|
||||
color: "gray",
|
||||
icon: BanknotesIcon,
|
||||
title: "Today's Money",
|
||||
value: "$53k",
|
||||
footer: {
|
||||
color: "text-green-500",
|
||||
value: "+55%",
|
||||
label: "than last week",
|
||||
},
|
||||
},
|
||||
{
|
||||
color: "gray",
|
||||
icon: UsersIcon,
|
||||
title: "Today's Users",
|
||||
value: "2,300",
|
||||
footer: {
|
||||
color: "text-green-500",
|
||||
value: "+3%",
|
||||
label: "than last month",
|
||||
},
|
||||
},
|
||||
{
|
||||
color: "gray",
|
||||
icon: UserPlusIcon,
|
||||
title: "New Clients",
|
||||
value: "3,462",
|
||||
footer: {
|
||||
color: "text-red-500",
|
||||
value: "-2%",
|
||||
label: "than yesterday",
|
||||
},
|
||||
},
|
||||
{
|
||||
color: "gray",
|
||||
icon: ChartBarIcon,
|
||||
title: "Sales",
|
||||
value: "$103,430",
|
||||
footer: {
|
||||
color: "text-green-500",
|
||||
value: "+5%",
|
||||
label: "than yesterday",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default statisticsCardsData;
|
||||
@@ -0,0 +1,131 @@
|
||||
import { chartsConfig } from "@/configs";
|
||||
|
||||
const websiteViewsChart = {
|
||||
type: "bar",
|
||||
height: 220,
|
||||
series: [
|
||||
{
|
||||
name: "Views",
|
||||
data: [50, 20, 10, 22, 50, 10, 40],
|
||||
},
|
||||
],
|
||||
options: {
|
||||
...chartsConfig,
|
||||
colors: "#388e3c",
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: "16%",
|
||||
borderRadius: 5,
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
...chartsConfig.xaxis,
|
||||
categories: ["M", "T", "W", "T", "F", "S", "S"],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const dailySalesChart = {
|
||||
type: "line",
|
||||
height: 220,
|
||||
series: [
|
||||
{
|
||||
name: "Sales",
|
||||
data: [50, 40, 300, 320, 500, 350, 200, 230, 500],
|
||||
},
|
||||
],
|
||||
options: {
|
||||
...chartsConfig,
|
||||
colors: ["#0288d1"],
|
||||
stroke: {
|
||||
lineCap: "round",
|
||||
},
|
||||
markers: {
|
||||
size: 5,
|
||||
},
|
||||
xaxis: {
|
||||
...chartsConfig.xaxis,
|
||||
categories: [
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec",
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const completedTaskChart = {
|
||||
type: "line",
|
||||
height: 220,
|
||||
series: [
|
||||
{
|
||||
name: "Sales",
|
||||
data: [50, 40, 300, 320, 500, 350, 200, 230, 500],
|
||||
},
|
||||
],
|
||||
options: {
|
||||
...chartsConfig,
|
||||
colors: ["#388e3c"],
|
||||
stroke: {
|
||||
lineCap: "round",
|
||||
},
|
||||
markers: {
|
||||
size: 5,
|
||||
},
|
||||
xaxis: {
|
||||
...chartsConfig.xaxis,
|
||||
categories: [
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec",
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
const completedTasksChart = {
|
||||
...completedTaskChart,
|
||||
series: [
|
||||
{
|
||||
name: "Tasks",
|
||||
data: [50, 40, 300, 220, 500, 250, 400, 230, 500],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const statisticsChartsData = [
|
||||
{
|
||||
color: "white",
|
||||
title: "Website View",
|
||||
description: "Last Campaign Performance",
|
||||
footer: "campaign sent 2 days ago",
|
||||
chart: websiteViewsChart,
|
||||
},
|
||||
{
|
||||
color: "white",
|
||||
title: "Daily Sales",
|
||||
description: "15% increase in today sales",
|
||||
footer: "updated 4 min ago",
|
||||
chart: dailySalesChart,
|
||||
},
|
||||
{
|
||||
color: "white",
|
||||
title: "Completed Tasks",
|
||||
description: "Last Campaign Performance",
|
||||
footer: "just updated",
|
||||
chart: completedTasksChart,
|
||||
},
|
||||
];
|
||||
|
||||
export default statisticsChartsData;
|
||||
@@ -0,0 +1,52 @@
|
||||
import { Routes, Route } from "react-router-dom";
|
||||
import {
|
||||
ChartPieIcon,
|
||||
UserIcon,
|
||||
UserPlusIcon,
|
||||
ArrowRightOnRectangleIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
import { Navbar, Footer } from "@/widgets/layout";
|
||||
import routes from "@/routes";
|
||||
|
||||
export function Auth() {
|
||||
const navbarRoutes = [
|
||||
{
|
||||
name: "dashboard",
|
||||
path: "/dashboard/home",
|
||||
icon: ChartPieIcon,
|
||||
},
|
||||
{
|
||||
name: "profile",
|
||||
path: "/dashboard/home",
|
||||
icon: UserIcon,
|
||||
},
|
||||
{
|
||||
name: "sign up",
|
||||
path: "/auth/sign-up",
|
||||
icon: UserPlusIcon,
|
||||
},
|
||||
{
|
||||
name: "sign in",
|
||||
path: "/auth/sign-in",
|
||||
icon: ArrowRightOnRectangleIcon,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="relative min-h-screen w-full">
|
||||
<Routes>
|
||||
{routes.map(
|
||||
({ layout, pages }) =>
|
||||
layout === "auth" &&
|
||||
pages.map(({ path, element }) => (
|
||||
<Route exact path={path} element={element} />
|
||||
))
|
||||
)}
|
||||
</Routes>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Auth.displayName = "/src/layout/Auth.jsx";
|
||||
|
||||
export default Auth;
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Routes, Route } from "react-router-dom";
|
||||
import { Cog6ToothIcon } from "@heroicons/react/24/solid";
|
||||
import { IconButton } from "@material-tailwind/react";
|
||||
import {
|
||||
Sidenav,
|
||||
DashboardNavbar,
|
||||
Configurator,
|
||||
Footer,
|
||||
} from "@/widgets/layout";
|
||||
import routes from "@/routes";
|
||||
import { useMaterialTailwindController, setOpenConfigurator } from "@/components";
|
||||
|
||||
export function Dashboard() {
|
||||
const [controller, dispatch] = useMaterialTailwindController();
|
||||
const { sidenavType } = controller;
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-blue-gray-50/50">
|
||||
<Sidenav
|
||||
routes={routes}
|
||||
brandImg={
|
||||
sidenavType === "dark" ? "/img/logo-ct.png" : "/img/logo-ct-dark.png"
|
||||
}
|
||||
/>
|
||||
<div className="p-4 xl:ml-80">
|
||||
<DashboardNavbar />
|
||||
<Configurator />
|
||||
<IconButton
|
||||
size="lg"
|
||||
color="white"
|
||||
className="fixed bottom-8 right-8 z-40 rounded-full shadow-blue-gray-900/10 xl:hidden"
|
||||
ripple={false}
|
||||
onClick={() => setOpenConfigurator(dispatch, true)}
|
||||
>
|
||||
<Cog6ToothIcon className="h-5 w-5" />
|
||||
</IconButton>
|
||||
<Routes>
|
||||
{routes.map(
|
||||
({ layout, pages }) =>
|
||||
layout === "dashboard" &&
|
||||
pages.map(({ path, element }) => (
|
||||
<Route exact path={path} element={element} />
|
||||
))
|
||||
)}
|
||||
</Routes>
|
||||
<div className="text-blue-gray-600">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Dashboard.displayName = "/src/layout/dashboard.jsx";
|
||||
|
||||
export default Dashboard;
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "@/layouts/dashboard";
|
||||
export * from "@/layouts/auth";
|
||||
+25
-5
@@ -1,17 +1,37 @@
|
||||
/**
|
||||
=========================================================
|
||||
* Material Tailwind Dashboard React - v2.1.0
|
||||
=========================================================
|
||||
* Product Page: https://www.creative-tim.com/product/material-tailwind-dashboard-react
|
||||
* Copyright 2023 Creative Tim (https://www.creative-tim.com)
|
||||
* Licensed under MIT (https://github.com/creativetimofficial/material-tailwind-dashboard-react/blob/main/LICENSE.md)
|
||||
* Coded by Creative Tim
|
||||
=========================================================
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*/
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import App from "./App.jsx";
|
||||
import ToastProvider from "./components/ToastProvider.jsx";
|
||||
import MaintenanceProvider from "./context/MaintenanceContext.jsx";
|
||||
import './index.css'; // Tailwind CSS
|
||||
import { ThemeProvider } from "@material-tailwind/react";
|
||||
import { MaterialTailwindControllerProvider } from "@/components";
|
||||
import "./tailwind.css";
|
||||
import ToastProvider from "@/components/ToastProvider.jsx";
|
||||
import MaintenanceProvider from "@/components/MaintenanceProvider.jsx";
|
||||
import PageProvider from "@/components/PageProvider.jsx";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<BrowserRouter>
|
||||
<MaintenanceProvider>
|
||||
<ToastProvider>
|
||||
<App />
|
||||
<PageProvider>
|
||||
<ThemeProvider>
|
||||
<MaterialTailwindControllerProvider>
|
||||
<App />
|
||||
</MaterialTailwindControllerProvider>
|
||||
</ThemeProvider>
|
||||
</PageProvider>
|
||||
</ToastProvider>
|
||||
</MaintenanceProvider>
|
||||
</BrowserRouter>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "@/pages/auth/sign-in";
|
||||
export * from "@/pages/auth/sign-up";
|
||||
@@ -0,0 +1,126 @@
|
||||
import {
|
||||
Card,
|
||||
Input,
|
||||
Checkbox,
|
||||
Button,
|
||||
Typography,
|
||||
} from "@material-tailwind/react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
|
||||
export function SignIn() {
|
||||
return (
|
||||
<section className="m-8 flex gap-4">
|
||||
<div className="w-full lg:w-3/5 mt-24">
|
||||
<div className="text-center">
|
||||
<Typography variant="h2" className="font-bold mb-4">Sign In</Typography>
|
||||
<Typography variant="paragraph" color="blue-gray" className="text-lg font-normal">Enter your email and password to Sign In.</Typography>
|
||||
</div>
|
||||
<form className="mt-8 mb-2 mx-auto w-80 max-w-screen-lg lg:w-1/2">
|
||||
<div className="mb-1 flex flex-col gap-6">
|
||||
<Typography variant="small" color="blue-gray" className="-mb-3 font-medium">
|
||||
Your email
|
||||
</Typography>
|
||||
<Input
|
||||
size="lg"
|
||||
placeholder="name@mail.com"
|
||||
className=" !border-t-blue-gray-200 focus:!border-t-gray-900"
|
||||
labelProps={{
|
||||
className: "before:content-none after:content-none",
|
||||
}}
|
||||
/>
|
||||
<Typography variant="small" color="blue-gray" className="-mb-3 font-medium">
|
||||
Password
|
||||
</Typography>
|
||||
<Input
|
||||
type="password"
|
||||
size="lg"
|
||||
placeholder="********"
|
||||
className=" !border-t-blue-gray-200 focus:!border-t-gray-900"
|
||||
labelProps={{
|
||||
className: "before:content-none after:content-none",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Checkbox
|
||||
label={
|
||||
<Typography
|
||||
variant="small"
|
||||
color="gray"
|
||||
className="flex items-center justify-start font-medium"
|
||||
>
|
||||
I agree the
|
||||
<a
|
||||
href="#"
|
||||
className="font-normal text-black transition-colors hover:text-gray-900 underline"
|
||||
>
|
||||
Terms and Conditions
|
||||
</a>
|
||||
</Typography>
|
||||
}
|
||||
containerProps={{ className: "-ml-2.5" }}
|
||||
/>
|
||||
<Button className="mt-6" fullWidth>
|
||||
Sign In
|
||||
</Button>
|
||||
|
||||
<div className="flex items-center justify-between gap-2 mt-6">
|
||||
<Checkbox
|
||||
label={
|
||||
<Typography
|
||||
variant="small"
|
||||
color="gray"
|
||||
className="flex items-center justify-start font-medium"
|
||||
>
|
||||
Subscribe me to newsletter
|
||||
</Typography>
|
||||
}
|
||||
containerProps={{ className: "-ml-2.5" }}
|
||||
/>
|
||||
<Typography variant="small" className="font-medium text-gray-900">
|
||||
<a href="#">
|
||||
Forgot Password
|
||||
</a>
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="space-y-4 mt-8">
|
||||
<Button size="lg" color="white" className="flex items-center gap-2 justify-center shadow-md" fullWidth>
|
||||
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clipPath="url(#clip0_1156_824)">
|
||||
<path d="M16.3442 8.18429C16.3442 7.64047 16.3001 7.09371 16.206 6.55872H8.66016V9.63937H12.9813C12.802 10.6329 12.2258 11.5119 11.3822 12.0704V14.0693H13.9602C15.4741 12.6759 16.3442 10.6182 16.3442 8.18429Z" fill="#4285F4" />
|
||||
<path d="M8.65974 16.0006C10.8174 16.0006 12.637 15.2922 13.9627 14.0693L11.3847 12.0704C10.6675 12.5584 9.7415 12.8347 8.66268 12.8347C6.5756 12.8347 4.80598 11.4266 4.17104 9.53357H1.51074V11.5942C2.86882 14.2956 5.63494 16.0006 8.65974 16.0006Z" fill="#34A853" />
|
||||
<path d="M4.16852 9.53356C3.83341 8.53999 3.83341 7.46411 4.16852 6.47054V4.40991H1.51116C0.376489 6.67043 0.376489 9.33367 1.51116 11.5942L4.16852 9.53356Z" fill="#FBBC04" />
|
||||
<path d="M8.65974 3.16644C9.80029 3.1488 10.9026 3.57798 11.7286 4.36578L14.0127 2.08174C12.5664 0.72367 10.6469 -0.0229773 8.65974 0.000539111C5.63494 0.000539111 2.86882 1.70548 1.51074 4.40987L4.1681 6.4705C4.8001 4.57449 6.57266 3.16644 8.65974 3.16644Z" fill="#EA4335" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1156_824">
|
||||
<rect width="16" height="16" fill="white" transform="translate(0.5)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span>Sign in With Google</span>
|
||||
</Button>
|
||||
<Button size="lg" color="white" className="flex items-center gap-2 justify-center shadow-md" fullWidth>
|
||||
<img src="/img/twitter-logo.svg" height={24} width={24} alt="" />
|
||||
<span>Sign in With Twitter</span>
|
||||
</Button>
|
||||
</div>
|
||||
<Typography variant="paragraph" className="text-center text-blue-gray-500 font-medium mt-4">
|
||||
Not registered?
|
||||
<Link to="/auth/sign-up" className="text-gray-900 ml-1">Create account</Link>
|
||||
</Typography>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<div className="w-2/5 h-full hidden lg:block">
|
||||
<img
|
||||
src="/img/pattern.png"
|
||||
className="h-full w-full object-cover rounded-3xl"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default SignIn;
|
||||
@@ -0,0 +1,94 @@
|
||||
import {
|
||||
Card,
|
||||
Input,
|
||||
Checkbox,
|
||||
Button,
|
||||
Typography,
|
||||
} from "@material-tailwind/react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
|
||||
export function SignUp() {
|
||||
return (
|
||||
<section className="m-8 flex">
|
||||
<div className="w-2/5 h-full hidden lg:block">
|
||||
<img
|
||||
src="/img/pattern.png"
|
||||
className="h-full w-full object-cover rounded-3xl"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full lg:w-3/5 flex flex-col items-center justify-center">
|
||||
<div className="text-center">
|
||||
<Typography variant="h2" className="font-bold mb-4">Join Us Today</Typography>
|
||||
<Typography variant="paragraph" color="blue-gray" className="text-lg font-normal">Enter your email and password to register.</Typography>
|
||||
</div>
|
||||
<form className="mt-8 mb-2 mx-auto w-80 max-w-screen-lg lg:w-1/2">
|
||||
<div className="mb-1 flex flex-col gap-6">
|
||||
<Typography variant="small" color="blue-gray" className="-mb-3 font-medium">
|
||||
Your email
|
||||
</Typography>
|
||||
<Input
|
||||
size="lg"
|
||||
placeholder="name@mail.com"
|
||||
className=" !border-t-blue-gray-200 focus:!border-t-gray-900"
|
||||
labelProps={{
|
||||
className: "before:content-none after:content-none",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Checkbox
|
||||
label={
|
||||
<Typography
|
||||
variant="small"
|
||||
color="gray"
|
||||
className="flex items-center justify-start font-medium"
|
||||
>
|
||||
I agree the
|
||||
<a
|
||||
href="#"
|
||||
className="font-normal text-black transition-colors hover:text-gray-900 underline"
|
||||
>
|
||||
Terms and Conditions
|
||||
</a>
|
||||
</Typography>
|
||||
}
|
||||
containerProps={{ className: "-ml-2.5" }}
|
||||
/>
|
||||
<Button className="mt-6" fullWidth>
|
||||
Register Now
|
||||
</Button>
|
||||
|
||||
<div className="space-y-4 mt-8">
|
||||
<Button size="lg" color="white" className="flex items-center gap-2 justify-center shadow-md" fullWidth>
|
||||
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clipPath="url(#clip0_1156_824)">
|
||||
<path d="M16.3442 8.18429C16.3442 7.64047 16.3001 7.09371 16.206 6.55872H8.66016V9.63937H12.9813C12.802 10.6329 12.2258 11.5119 11.3822 12.0704V14.0693H13.9602C15.4741 12.6759 16.3442 10.6182 16.3442 8.18429Z" fill="#4285F4" />
|
||||
<path d="M8.65974 16.0006C10.8174 16.0006 12.637 15.2922 13.9627 14.0693L11.3847 12.0704C10.6675 12.5584 9.7415 12.8347 8.66268 12.8347C6.5756 12.8347 4.80598 11.4266 4.17104 9.53357H1.51074V11.5942C2.86882 14.2956 5.63494 16.0006 8.65974 16.0006Z" fill="#34A853" />
|
||||
<path d="M4.16852 9.53356C3.83341 8.53999 3.83341 7.46411 4.16852 6.47054V4.40991H1.51116C0.376489 6.67043 0.376489 9.33367 1.51116 11.5942L4.16852 9.53356Z" fill="#FBBC04" />
|
||||
<path d="M8.65974 3.16644C9.80029 3.1488 10.9026 3.57798 11.7286 4.36578L14.0127 2.08174C12.5664 0.72367 10.6469 -0.0229773 8.65974 0.000539111C5.63494 0.000539111 2.86882 1.70548 1.51074 4.40987L4.1681 6.4705C4.8001 4.57449 6.57266 3.16644 8.65974 3.16644Z" fill="#EA4335" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1156_824">
|
||||
<rect width="16" height="16" fill="white" transform="translate(0.5)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span>Sign in With Google</span>
|
||||
</Button>
|
||||
<Button size="lg" color="white" className="flex items-center gap-2 justify-center shadow-md" fullWidth>
|
||||
<img src="/img/twitter-logo.svg" height={24} width={24} alt="" />
|
||||
<span>Sign in With Twitter</span>
|
||||
</Button>
|
||||
</div>
|
||||
<Typography variant="paragraph" className="text-center text-blue-gray-500 font-medium mt-4">
|
||||
Already have an account?
|
||||
<Link to="/auth/sign-in" className="text-gray-900 ml-1">Sign in</Link>
|
||||
</Typography>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default SignUp;
|
||||
@@ -0,0 +1,258 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Typography,
|
||||
Card,
|
||||
CardHeader,
|
||||
CardBody,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuHandler,
|
||||
MenuList,
|
||||
MenuItem,
|
||||
Avatar,
|
||||
Tooltip,
|
||||
Progress,
|
||||
} from "@material-tailwind/react";
|
||||
import {
|
||||
EllipsisVerticalIcon,
|
||||
ArrowUpIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { StatisticsCard } from "@/widgets/cards";
|
||||
import { StatisticsChart } from "@/widgets/charts";
|
||||
import {
|
||||
statisticsCardsData,
|
||||
statisticsChartsData,
|
||||
projectsTableData,
|
||||
ordersOverviewData,
|
||||
} from "@/data";
|
||||
import { CheckCircleIcon, ClockIcon } from "@heroicons/react/24/solid";
|
||||
|
||||
export function Home() {
|
||||
return (
|
||||
<div className="mt-12">
|
||||
<div className="mb-12 grid gap-y-10 gap-x-6 md:grid-cols-2 xl:grid-cols-4">
|
||||
{statisticsCardsData.map(({ icon, title, footer, ...rest }) => (
|
||||
<StatisticsCard
|
||||
key={title}
|
||||
{...rest}
|
||||
title={title}
|
||||
icon={React.createElement(icon, {
|
||||
className: "w-6 h-6 text-white",
|
||||
})}
|
||||
footer={
|
||||
<Typography className="font-normal text-blue-gray-600">
|
||||
<strong className={footer.color}>{footer.value}</strong>
|
||||
{footer.label}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="mb-6 grid grid-cols-1 gap-y-12 gap-x-6 md:grid-cols-2 xl:grid-cols-3">
|
||||
{statisticsChartsData.map((props) => (
|
||||
<StatisticsChart
|
||||
key={props.title}
|
||||
{...props}
|
||||
footer={
|
||||
<Typography
|
||||
variant="small"
|
||||
className="flex items-center font-normal text-blue-gray-600"
|
||||
>
|
||||
<ClockIcon strokeWidth={2} className="h-4 w-4 text-blue-gray-400" />
|
||||
{props.footer}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="mb-4 grid grid-cols-1 gap-6 xl:grid-cols-3">
|
||||
<Card className="overflow-hidden xl:col-span-2 border border-blue-gray-100 shadow-sm">
|
||||
<CardHeader
|
||||
floated={false}
|
||||
shadow={false}
|
||||
color="transparent"
|
||||
className="m-0 flex items-center justify-between p-6"
|
||||
>
|
||||
<div>
|
||||
<Typography variant="h6" color="blue-gray" className="mb-1">
|
||||
Projects
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="small"
|
||||
className="flex items-center gap-1 font-normal text-blue-gray-600"
|
||||
>
|
||||
<CheckCircleIcon strokeWidth={3} className="h-4 w-4 text-blue-gray-200" />
|
||||
<strong>30 done</strong> this month
|
||||
</Typography>
|
||||
</div>
|
||||
<Menu placement="left-start">
|
||||
<MenuHandler>
|
||||
<IconButton size="sm" variant="text" color="blue-gray">
|
||||
<EllipsisVerticalIcon
|
||||
strokeWidth={3}
|
||||
fill="currenColor"
|
||||
className="h-6 w-6"
|
||||
/>
|
||||
</IconButton>
|
||||
</MenuHandler>
|
||||
<MenuList>
|
||||
<MenuItem>Action</MenuItem>
|
||||
<MenuItem>Another Action</MenuItem>
|
||||
<MenuItem>Something else here</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</CardHeader>
|
||||
<CardBody className="overflow-x-scroll px-0 pt-0 pb-2">
|
||||
<table className="w-full min-w-[640px] table-auto">
|
||||
<thead>
|
||||
<tr>
|
||||
{["companies", "members", "budget", "completion"].map(
|
||||
(el) => (
|
||||
<th
|
||||
key={el}
|
||||
className="border-b border-blue-gray-50 py-3 px-6 text-left"
|
||||
>
|
||||
<Typography
|
||||
variant="small"
|
||||
className="text-[11px] font-medium uppercase text-blue-gray-400"
|
||||
>
|
||||
{el}
|
||||
</Typography>
|
||||
</th>
|
||||
)
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{projectsTableData.map(
|
||||
({ img, name, members, budget, completion }, key) => {
|
||||
const className = `py-3 px-5 ${
|
||||
key === projectsTableData.length - 1
|
||||
? ""
|
||||
: "border-b border-blue-gray-50"
|
||||
}`;
|
||||
|
||||
return (
|
||||
<tr key={name}>
|
||||
<td className={className}>
|
||||
<div className="flex items-center gap-4">
|
||||
<Avatar src={img} alt={name} size="sm" />
|
||||
<Typography
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="font-bold"
|
||||
>
|
||||
{name}
|
||||
</Typography>
|
||||
</div>
|
||||
</td>
|
||||
<td className={className}>
|
||||
{members.map(({ img, name }, key) => (
|
||||
<Tooltip key={name} content={name}>
|
||||
<Avatar
|
||||
src={img}
|
||||
alt={name}
|
||||
size="xs"
|
||||
variant="circular"
|
||||
className={`cursor-pointer border-2 border-white ${
|
||||
key === 0 ? "" : "-ml-2.5"
|
||||
}`}
|
||||
/>
|
||||
</Tooltip>
|
||||
))}
|
||||
</td>
|
||||
<td className={className}>
|
||||
<Typography
|
||||
variant="small"
|
||||
className="text-xs font-medium text-blue-gray-600"
|
||||
>
|
||||
{budget}
|
||||
</Typography>
|
||||
</td>
|
||||
<td className={className}>
|
||||
<div className="w-10/12">
|
||||
<Typography
|
||||
variant="small"
|
||||
className="mb-1 block text-xs font-medium text-blue-gray-600"
|
||||
>
|
||||
{completion}%
|
||||
</Typography>
|
||||
<Progress
|
||||
value={completion}
|
||||
variant="gradient"
|
||||
color={completion === 100 ? "green" : "blue"}
|
||||
className="h-1"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card className="border border-blue-gray-100 shadow-sm">
|
||||
<CardHeader
|
||||
floated={false}
|
||||
shadow={false}
|
||||
color="transparent"
|
||||
className="m-0 p-6"
|
||||
>
|
||||
<Typography variant="h6" color="blue-gray" className="mb-2">
|
||||
Orders Overview
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="small"
|
||||
className="flex items-center gap-1 font-normal text-blue-gray-600"
|
||||
>
|
||||
<ArrowUpIcon
|
||||
strokeWidth={3}
|
||||
className="h-3.5 w-3.5 text-green-500"
|
||||
/>
|
||||
<strong>24%</strong> this month
|
||||
</Typography>
|
||||
</CardHeader>
|
||||
<CardBody className="pt-0">
|
||||
{ordersOverviewData.map(
|
||||
({ icon, color, title, description }, key) => (
|
||||
<div key={title} className="flex items-start gap-4 py-3">
|
||||
<div
|
||||
className={`relative p-1 after:absolute after:-bottom-6 after:left-2/4 after:w-0.5 after:-translate-x-2/4 after:bg-blue-gray-50 after:content-[''] ${
|
||||
key === ordersOverviewData.length - 1
|
||||
? "after:h-0"
|
||||
: "after:h-4/6"
|
||||
}`}
|
||||
>
|
||||
{React.createElement(icon, {
|
||||
className: `!w-5 !h-5 ${color}`,
|
||||
})}
|
||||
</div>
|
||||
<div>
|
||||
<Typography
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="block font-medium"
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography
|
||||
as="span"
|
||||
variant="small"
|
||||
className="text-xs font-medium text-blue-gray-500"
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Home;
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "@/pages/dashboard/stacks";
|
||||
export * from "@/pages/dashboard/maintenance";
|
||||
export * from "@/pages/dashboard/logs";
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,88 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Typography,
|
||||
Alert,
|
||||
Card,
|
||||
CardHeader,
|
||||
CardBody,
|
||||
} from "@material-tailwind/react";
|
||||
import { InformationCircleIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
export function Notifications() {
|
||||
const [showAlerts, setShowAlerts] = React.useState({
|
||||
blue: true,
|
||||
green: true,
|
||||
orange: true,
|
||||
red: true,
|
||||
});
|
||||
const [showAlertsWithIcon, setShowAlertsWithIcon] = React.useState({
|
||||
blue: true,
|
||||
green: true,
|
||||
orange: true,
|
||||
red: true,
|
||||
});
|
||||
const alerts = ["gray", "green", "orange", "red"];
|
||||
|
||||
return (
|
||||
<div className="mx-auto my-20 flex max-w-screen-lg flex-col gap-8">
|
||||
<Card>
|
||||
<CardHeader
|
||||
color="transparent"
|
||||
floated={false}
|
||||
shadow={false}
|
||||
className="m-0 p-4"
|
||||
>
|
||||
<Typography variant="h5" color="blue-gray">
|
||||
Alerts
|
||||
</Typography>
|
||||
</CardHeader>
|
||||
<CardBody className="flex flex-col gap-4 p-4">
|
||||
{alerts.map((color) => (
|
||||
<Alert
|
||||
key={color}
|
||||
open={showAlerts[color]}
|
||||
color={color}
|
||||
onClose={() => setShowAlerts((current) => ({ ...current, [color]: false }))}
|
||||
>
|
||||
A simple {color} alert with an <a href="#">example link</a>. Give
|
||||
it a click if you like.
|
||||
</Alert>
|
||||
))}
|
||||
</CardBody>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader
|
||||
color="transparent"
|
||||
floated={false}
|
||||
shadow={false}
|
||||
className="m-0 p-4"
|
||||
>
|
||||
<Typography variant="h5" color="blue-gray">
|
||||
Alerts with Icon
|
||||
</Typography>
|
||||
</CardHeader>
|
||||
<CardBody className="flex flex-col gap-4 p-4">
|
||||
{alerts.map((color) => (
|
||||
<Alert
|
||||
key={color}
|
||||
open={showAlertsWithIcon[color]}
|
||||
color={color}
|
||||
icon={
|
||||
<InformationCircleIcon strokeWidth={2} className="h-6 w-6" />
|
||||
}
|
||||
onClose={() => setShowAlertsWithIcon((current) => ({
|
||||
...current,
|
||||
[color]: false,
|
||||
}))}
|
||||
>
|
||||
A simple {color} alert with an <a href="#">example link</a>. Give
|
||||
it a click if you like.
|
||||
</Alert>
|
||||
))}
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Notifications;
|
||||
@@ -0,0 +1,221 @@
|
||||
import {
|
||||
Card,
|
||||
CardBody,
|
||||
CardHeader,
|
||||
CardFooter,
|
||||
Avatar,
|
||||
Typography,
|
||||
Tabs,
|
||||
TabsHeader,
|
||||
Tab,
|
||||
Switch,
|
||||
Tooltip,
|
||||
Button,
|
||||
} from "@material-tailwind/react";
|
||||
import {
|
||||
HomeIcon,
|
||||
ChatBubbleLeftEllipsisIcon,
|
||||
Cog6ToothIcon,
|
||||
PencilIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
import { Link } from "react-router-dom";
|
||||
import { ProfileInfoCard, MessageCard } from "@/widgets/cards";
|
||||
import { platformSettingsData, conversationsData, projectsData } from "@/data";
|
||||
|
||||
export function Profile() {
|
||||
return (
|
||||
<>
|
||||
<div className="relative mt-8 h-72 w-full overflow-hidden rounded-xl bg-[url('/img/background-image.png')] bg-cover bg-center">
|
||||
<div className="absolute inset-0 h-full w-full bg-gray-900/75" />
|
||||
</div>
|
||||
<Card className="mx-3 -mt-16 mb-6 lg:mx-4 border border-blue-gray-100">
|
||||
<CardBody className="p-4">
|
||||
<div className="mb-10 flex items-center justify-between flex-wrap gap-6">
|
||||
<div className="flex items-center gap-6">
|
||||
<Avatar
|
||||
src="/img/bruce-mars.jpeg"
|
||||
alt="bruce-mars"
|
||||
size="xl"
|
||||
variant="rounded"
|
||||
className="rounded-lg shadow-lg shadow-blue-gray-500/40"
|
||||
/>
|
||||
<div>
|
||||
<Typography variant="h5" color="blue-gray" className="mb-1">
|
||||
Richard Davis
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="small"
|
||||
className="font-normal text-blue-gray-600"
|
||||
>
|
||||
CEO / Co-Founder
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-96">
|
||||
<Tabs value="app">
|
||||
<TabsHeader>
|
||||
<Tab value="app">
|
||||
<HomeIcon className="-mt-1 mr-2 inline-block h-5 w-5" />
|
||||
App
|
||||
</Tab>
|
||||
<Tab value="message">
|
||||
<ChatBubbleLeftEllipsisIcon className="-mt-0.5 mr-2 inline-block h-5 w-5" />
|
||||
Message
|
||||
</Tab>
|
||||
<Tab value="settings">
|
||||
<Cog6ToothIcon className="-mt-1 mr-2 inline-block h-5 w-5" />
|
||||
Settings
|
||||
</Tab>
|
||||
</TabsHeader>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
<div className="gird-cols-1 mb-12 grid gap-12 px-4 lg:grid-cols-2 xl:grid-cols-3">
|
||||
<div>
|
||||
<Typography variant="h6" color="blue-gray" className="mb-3">
|
||||
Platform Settings
|
||||
</Typography>
|
||||
<div className="flex flex-col gap-12">
|
||||
{platformSettingsData.map(({ title, options }) => (
|
||||
<div key={title}>
|
||||
<Typography className="mb-4 block text-xs font-semibold uppercase text-blue-gray-500">
|
||||
{title}
|
||||
</Typography>
|
||||
<div className="flex flex-col gap-6">
|
||||
{options.map(({ checked, label }) => (
|
||||
<Switch
|
||||
key={label}
|
||||
id={label}
|
||||
label={label}
|
||||
defaultChecked={checked}
|
||||
labelProps={{
|
||||
className: "text-sm font-normal text-blue-gray-500",
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<ProfileInfoCard
|
||||
title="Profile Information"
|
||||
description="Hi, I'm Alec Thompson, Decisions: If you can't decide, the answer is no. If two equally difficult paths, choose the one more painful in the short term (pain avoidance is creating an illusion of equality)."
|
||||
details={{
|
||||
"first name": "Alec M. Thompson",
|
||||
mobile: "(44) 123 1234 123",
|
||||
email: "alecthompson@mail.com",
|
||||
location: "USA",
|
||||
social: (
|
||||
<div className="flex items-center gap-4">
|
||||
<i className="fa-brands fa-facebook text-blue-700" />
|
||||
<i className="fa-brands fa-twitter text-blue-400" />
|
||||
<i className="fa-brands fa-instagram text-purple-500" />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
action={
|
||||
<Tooltip content="Edit Profile">
|
||||
<PencilIcon className="h-4 w-4 cursor-pointer text-blue-gray-500" />
|
||||
</Tooltip>
|
||||
}
|
||||
/>
|
||||
<div>
|
||||
<Typography variant="h6" color="blue-gray" className="mb-3">
|
||||
Platform Settings
|
||||
</Typography>
|
||||
<ul className="flex flex-col gap-6">
|
||||
{conversationsData.map((props) => (
|
||||
<MessageCard
|
||||
key={props.name}
|
||||
{...props}
|
||||
action={
|
||||
<Button variant="text" size="sm">
|
||||
reply
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-4 pb-4">
|
||||
<Typography variant="h6" color="blue-gray" className="mb-2">
|
||||
Projects
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="small"
|
||||
className="font-normal text-blue-gray-500"
|
||||
>
|
||||
Architects design houses
|
||||
</Typography>
|
||||
<div className="mt-6 grid grid-cols-1 gap-12 md:grid-cols-2 xl:grid-cols-4">
|
||||
{projectsData.map(
|
||||
({ img, title, description, tag, route, members }) => (
|
||||
<Card key={title} color="transparent" shadow={false}>
|
||||
<CardHeader
|
||||
floated={false}
|
||||
color="gray"
|
||||
className="mx-0 mt-0 mb-4 h-64 xl:h-40"
|
||||
>
|
||||
<img
|
||||
src={img}
|
||||
alt={title}
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
</CardHeader>
|
||||
<CardBody className="py-0 px-1">
|
||||
<Typography
|
||||
variant="small"
|
||||
className="font-normal text-blue-gray-500"
|
||||
>
|
||||
{tag}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="h5"
|
||||
color="blue-gray"
|
||||
className="mt-1 mb-2"
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="small"
|
||||
className="font-normal text-blue-gray-500"
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
</CardBody>
|
||||
<CardFooter className="mt-6 flex items-center justify-between py-0 px-1">
|
||||
<Link to={route}>
|
||||
<Button variant="outlined" size="sm">
|
||||
view project
|
||||
</Button>
|
||||
</Link>
|
||||
<div>
|
||||
{members.map(({ img, name }, key) => (
|
||||
<Tooltip key={name} content={name}>
|
||||
<Avatar
|
||||
src={img}
|
||||
alt={name}
|
||||
size="xs"
|
||||
variant="circular"
|
||||
className={`cursor-pointer border-2 border-white ${
|
||||
key === 0 ? "" : "-ml-2.5"
|
||||
}`}
|
||||
/>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Profile;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,57 @@
|
||||
import {
|
||||
Square3Stack3DIcon,
|
||||
WrenchScrewdriverIcon,
|
||||
ListBulletIcon
|
||||
} from "@heroicons/react/24/solid";
|
||||
import { Stacks, Maintenance, Logs } from "@/pages/dashboard";
|
||||
import { SignIn, SignUp } from "@/pages/auth";
|
||||
|
||||
const icon = {
|
||||
className: "w-5 h-5 text-inherit",
|
||||
};
|
||||
|
||||
export const routes = [
|
||||
{
|
||||
layout: "dashboard",
|
||||
pages: [
|
||||
{
|
||||
icon: <Square3Stack3DIcon {...icon} />,
|
||||
name: "stacks",
|
||||
path: "/stacks",
|
||||
element: <Stacks />,
|
||||
},
|
||||
{
|
||||
icon: <WrenchScrewdriverIcon {...icon} />,
|
||||
name: "wartung",
|
||||
path: "/maintenance",
|
||||
element: <Maintenance />,
|
||||
},
|
||||
{
|
||||
icon: <ListBulletIcon {...icon} />,
|
||||
name: "logs",
|
||||
path: "/logs",
|
||||
element: <Logs />,
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// title: "auth pages",
|
||||
// layout: "auth",
|
||||
// pages: [
|
||||
// {
|
||||
// icon: <ServerStackIcon {...icon} />,
|
||||
// name: "sign in",
|
||||
// path: "/sign-in",
|
||||
// element: <SignIn />,
|
||||
// },
|
||||
// {
|
||||
// icon: <RectangleStackIcon {...icon} />,
|
||||
// name: "sign up",
|
||||
// path: "/sign-up",
|
||||
// element: <SignUp />,
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
];
|
||||
|
||||
export default routes;
|
||||
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "@/widgets/cards/statistics-card";
|
||||
export * from "@/widgets/cards/profile-info-card";
|
||||
export * from "@/widgets/cards/message-card";
|
||||
@@ -0,0 +1,45 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { Avatar, Typography } from "@material-tailwind/react";
|
||||
|
||||
export function MessageCard({ img, name, message, action }) {
|
||||
return (
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<Avatar
|
||||
src={img}
|
||||
alt={name}
|
||||
variant="rounded"
|
||||
className="shadow-lg shadow-blue-gray-500/25"
|
||||
/>
|
||||
<div>
|
||||
<Typography
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="mb-1 font-semibold"
|
||||
>
|
||||
{name}
|
||||
</Typography>
|
||||
<Typography className="text-xs font-normal text-blue-gray-400">
|
||||
{message}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
{action}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
MessageCard.defaultProps = {
|
||||
action: null,
|
||||
};
|
||||
|
||||
MessageCard.propTypes = {
|
||||
img: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
message: PropTypes.node.isRequired,
|
||||
action: PropTypes.node,
|
||||
};
|
||||
|
||||
MessageCard.displayName = "/src/widgets/cards/message-card.jsx";
|
||||
|
||||
export default MessageCard;
|
||||
@@ -0,0 +1,79 @@
|
||||
import PropTypes from "prop-types";
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardBody,
|
||||
Typography,
|
||||
} from "@material-tailwind/react";
|
||||
|
||||
export function ProfileInfoCard({ title, description, details, action }) {
|
||||
return (
|
||||
<Card color="transparent" shadow={false}>
|
||||
<CardHeader
|
||||
color="transparent"
|
||||
shadow={false}
|
||||
floated={false}
|
||||
className="mx-0 mt-0 mb-4 flex items-center justify-between gap-4"
|
||||
>
|
||||
<Typography variant="h6" color="blue-gray">
|
||||
{title}
|
||||
</Typography>
|
||||
{action}
|
||||
</CardHeader>
|
||||
<CardBody className="p-0">
|
||||
{description && (
|
||||
<Typography
|
||||
variant="small"
|
||||
className="font-normal text-blue-gray-500"
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
{description && details ? (
|
||||
<hr className="my-8 border-blue-gray-50" />
|
||||
) : null}
|
||||
{details && (
|
||||
<ul className="flex flex-col gap-4 p-0">
|
||||
{Object.keys(details).map((el, key) => (
|
||||
<li key={key} className="flex items-center gap-4">
|
||||
<Typography
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="font-semibold capitalize"
|
||||
>
|
||||
{el}:
|
||||
</Typography>
|
||||
{typeof details[el] === "string" ? (
|
||||
<Typography
|
||||
variant="small"
|
||||
className="font-normal text-blue-gray-500"
|
||||
>
|
||||
{details[el]}
|
||||
</Typography>
|
||||
) : (
|
||||
details[el]
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
ProfileInfoCard.defaultProps = {
|
||||
action: null,
|
||||
description: null,
|
||||
details: {},
|
||||
};
|
||||
|
||||
ProfileInfoCard.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
description: PropTypes.node,
|
||||
details: PropTypes.object,
|
||||
};
|
||||
|
||||
ProfileInfoCard.displayName = "/src/widgets/cards/profile-info-card.jsx";
|
||||
|
||||
export default ProfileInfoCard;
|
||||
@@ -0,0 +1,75 @@
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardBody,
|
||||
CardFooter,
|
||||
Typography,
|
||||
} from "@material-tailwind/react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export function StatisticsCard({ color, icon, title, value, footer }) {
|
||||
return (
|
||||
<Card className="border border-blue-gray-100 shadow-sm">
|
||||
<CardHeader
|
||||
variant="gradient"
|
||||
color={color}
|
||||
floated={false}
|
||||
shadow={false}
|
||||
className="absolute grid h-12 w-12 place-items-center"
|
||||
>
|
||||
{icon}
|
||||
</CardHeader>
|
||||
<CardBody className="p-4 text-right">
|
||||
<Typography variant="small" className="font-normal text-blue-gray-600">
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography variant="h4" color="blue-gray">
|
||||
{value}
|
||||
</Typography>
|
||||
</CardBody>
|
||||
{footer && (
|
||||
<CardFooter className="border-t border-blue-gray-50 p-4">
|
||||
{footer}
|
||||
</CardFooter>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
StatisticsCard.defaultProps = {
|
||||
color: "blue",
|
||||
footer: null,
|
||||
};
|
||||
|
||||
StatisticsCard.propTypes = {
|
||||
color: PropTypes.oneOf([
|
||||
"white",
|
||||
"blue-gray",
|
||||
"gray",
|
||||
"brown",
|
||||
"deep-orange",
|
||||
"orange",
|
||||
"amber",
|
||||
"yellow",
|
||||
"lime",
|
||||
"light-green",
|
||||
"green",
|
||||
"teal",
|
||||
"cyan",
|
||||
"light-blue",
|
||||
"blue",
|
||||
"indigo",
|
||||
"deep-purple",
|
||||
"purple",
|
||||
"pink",
|
||||
"red",
|
||||
]),
|
||||
icon: PropTypes.node.isRequired,
|
||||
title: PropTypes.node.isRequired,
|
||||
value: PropTypes.node.isRequired,
|
||||
footer: PropTypes.node,
|
||||
};
|
||||
|
||||
StatisticsCard.displayName = "/src/widgets/cards/statistics-card.jsx";
|
||||
|
||||
export default StatisticsCard;
|
||||
@@ -0,0 +1 @@
|
||||
export * from "@/widgets/charts/statistics-chart";
|
||||
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardBody,
|
||||
CardFooter,
|
||||
Typography,
|
||||
} from "@material-tailwind/react";
|
||||
import PropTypes from "prop-types";
|
||||
import Chart from "react-apexcharts";
|
||||
|
||||
export function StatisticsChart({ color, chart, title, description, footer }) {
|
||||
return (
|
||||
<Card className="border border-blue-gray-100 shadow-sm">
|
||||
<CardHeader variant="gradient" color={color} floated={false} shadow={false}>
|
||||
<Chart {...chart} />
|
||||
</CardHeader>
|
||||
<CardBody className="px-6 pt-0">
|
||||
<Typography variant="h6" color="blue-gray">
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography variant="small" className="font-normal text-blue-gray-600">
|
||||
{description}
|
||||
</Typography>
|
||||
</CardBody>
|
||||
{footer && (
|
||||
<CardFooter className="border-t border-blue-gray-50 px-6 py-5">
|
||||
{footer}
|
||||
</CardFooter>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
StatisticsChart.defaultProps = {
|
||||
color: "blue",
|
||||
footer: null,
|
||||
};
|
||||
|
||||
StatisticsChart.propTypes = {
|
||||
color: PropTypes.oneOf([
|
||||
"white",
|
||||
"blue-gray",
|
||||
"gray",
|
||||
"brown",
|
||||
"deep-orange",
|
||||
"orange",
|
||||
"amber",
|
||||
"yellow",
|
||||
"lime",
|
||||
"light-green",
|
||||
"green",
|
||||
"teal",
|
||||
"cyan",
|
||||
"light-blue",
|
||||
"blue",
|
||||
"indigo",
|
||||
"deep-purple",
|
||||
"purple",
|
||||
"pink",
|
||||
"red",
|
||||
]),
|
||||
chart: PropTypes.object.isRequired,
|
||||
title: PropTypes.node.isRequired,
|
||||
description: PropTypes.node.isRequired,
|
||||
footer: PropTypes.node,
|
||||
};
|
||||
|
||||
StatisticsChart.displayName = "/src/widgets/charts/statistics-chart.jsx";
|
||||
|
||||
export default StatisticsChart;
|
||||
@@ -0,0 +1,127 @@
|
||||
import React from "react";
|
||||
import { XMarkIcon } from "@heroicons/react/24/outline";
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
Switch,
|
||||
Typography,
|
||||
Chip,
|
||||
} from "@material-tailwind/react";
|
||||
import {
|
||||
useMaterialTailwindController,
|
||||
setOpenConfigurator,
|
||||
setSidenavColor,
|
||||
setSidenavType,
|
||||
setFixedNavbar,
|
||||
} from "@/components";
|
||||
|
||||
function formatNumber(number, decPlaces) {
|
||||
decPlaces = Math.pow(10, decPlaces);
|
||||
|
||||
const abbrev = ["K", "M", "B", "T"];
|
||||
|
||||
for (let i = abbrev.length - 1; i >= 0; i--) {
|
||||
var size = Math.pow(10, (i + 1) * 3);
|
||||
|
||||
if (size <= number) {
|
||||
number = Math.round((number * decPlaces) / size) / decPlaces;
|
||||
|
||||
if (number == 1000 && i < abbrev.length - 1) {
|
||||
number = 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
number += abbrev[i];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
export function Configurator() {
|
||||
const [controller, dispatch] = useMaterialTailwindController();
|
||||
const { openConfigurator, sidenavColor, sidenavType, fixedNavbar } =
|
||||
controller;
|
||||
const [stars, setStars] = React.useState(0);
|
||||
|
||||
const sidenavColors = {
|
||||
dark: "from-black to-black border-gray-200",
|
||||
green: "from-green-400 to-green-600",
|
||||
orange: "from-orange-400 to-orange-600",
|
||||
red: "from-red-400 to-red-600",
|
||||
pink: "from-pink-400 to-pink-600",
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
const stars = fetch(
|
||||
"https://api.github.com/repos/creativetimofficial/material-tailwind-dashboard-react"
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((data) => setStars(formatNumber(data.stargazers_count, 1)));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={`fixed top-0 right-0 z-50 h-screen w-96 bg-white px-2.5 shadow-lg transition-transform duration-300 ${
|
||||
openConfigurator ? "translate-x-0" : "translate-x-96"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start justify-between px-6 pt-8 pb-6">
|
||||
<div>
|
||||
<Typography variant="h5" color="blue-gray">
|
||||
Dashboard Configurator
|
||||
</Typography>
|
||||
<Typography className="font-normal text-blue-gray-600">
|
||||
See our dashboard options.
|
||||
</Typography>
|
||||
</div>
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="blue-gray"
|
||||
onClick={() => setOpenConfigurator(dispatch, false)}
|
||||
>
|
||||
<XMarkIcon strokeWidth={2.5} className="h-5 w-5" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="py-4 px-6">
|
||||
<div className="mb-12">
|
||||
<Typography variant="h6" color="blue-gray">
|
||||
Sidenav Colors
|
||||
</Typography>
|
||||
<div className="mt-3 flex items-center gap-2">
|
||||
{Object.keys(sidenavColors).map((color) => (
|
||||
<span
|
||||
key={color}
|
||||
className={`h-6 w-6 cursor-pointer rounded-full border bg-gradient-to-br transition-transform hover:scale-105 ${
|
||||
sidenavColors[color]
|
||||
} ${
|
||||
sidenavColor === color ? "border-black" : "border-transparent"
|
||||
}`}
|
||||
onClick={() => setSidenavColor(dispatch, color)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-12">
|
||||
<hr />
|
||||
<div className="flex items-center justify-between py-5">
|
||||
<Typography variant="h6" color="blue-gray">
|
||||
Navbar Fixed
|
||||
</Typography>
|
||||
<Switch defaultChecked
|
||||
id="navbar-fixed"
|
||||
value={fixedNavbar}
|
||||
onChange={() => setFixedNavbar(dispatch, !fixedNavbar)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
Configurator.displayName = "/src/widgets/layout/configurator.jsx";
|
||||
|
||||
export default Configurator;
|
||||
@@ -0,0 +1,169 @@
|
||||
import { useLocation, Link } from "react-router-dom";
|
||||
import {
|
||||
Navbar,
|
||||
Typography,
|
||||
Button,
|
||||
IconButton,
|
||||
Breadcrumbs,
|
||||
Menu,
|
||||
MenuHandler,
|
||||
MenuList,
|
||||
MenuItem,
|
||||
Avatar,
|
||||
} from "@material-tailwind/react";
|
||||
import {
|
||||
UserCircleIcon,
|
||||
Cog6ToothIcon,
|
||||
BellIcon,
|
||||
ClockIcon,
|
||||
CreditCardIcon,
|
||||
Bars3Icon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
import {
|
||||
useMaterialTailwindController,
|
||||
setOpenConfigurator,
|
||||
setOpenSidenav,
|
||||
} from "@/components";
|
||||
|
||||
export function DashboardNavbar() {
|
||||
const [controller, dispatch] = useMaterialTailwindController();
|
||||
const { fixedNavbar, openSidenav } = controller;
|
||||
const { pathname } = useLocation();
|
||||
const [layout, page] = pathname.split("/").filter((el) => el !== "");
|
||||
|
||||
return (
|
||||
<Navbar
|
||||
color={fixedNavbar ? "white" : "transparent"}
|
||||
className={`rounded-xl transition-all ${
|
||||
fixedNavbar
|
||||
? "sticky top-4 z-40 py-3 shadow-md shadow-blue-gray-500/5"
|
||||
: "px-0 py-1"
|
||||
}`}
|
||||
fullWidth
|
||||
blurred={fixedNavbar}
|
||||
>
|
||||
<div className="flex justify-between gap-6 flex-row items-center">
|
||||
<div className="capitalize">
|
||||
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="blue-gray"
|
||||
className="grid xl:hidden"
|
||||
onClick={() => setOpenSidenav(dispatch, !openSidenav)}
|
||||
>
|
||||
<Bars3Icon strokeWidth={3} className="h-6 w-6 text-blue-gray-500" />
|
||||
</IconButton>
|
||||
{/* <Link to="/auth/sign-in">
|
||||
<Button
|
||||
variant="text"
|
||||
color="blue-gray"
|
||||
className="hidden items-center gap-1 px-4 xl:flex normal-case"
|
||||
>
|
||||
<UserCircleIcon className="h-5 w-5 text-blue-gray-500" />
|
||||
Sign In
|
||||
</Button>
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="blue-gray"
|
||||
className="grid xl:hidden"
|
||||
>
|
||||
<UserCircleIcon className="h-5 w-5 text-blue-gray-500" />
|
||||
</IconButton>
|
||||
</Link>
|
||||
<Menu>
|
||||
<MenuHandler>
|
||||
<IconButton variant="text" color="blue-gray">
|
||||
<BellIcon className="h-5 w-5 text-blue-gray-500" />
|
||||
</IconButton>
|
||||
</MenuHandler>
|
||||
<MenuList className="w-max border-0">
|
||||
<MenuItem className="flex items-center gap-3">
|
||||
<Avatar
|
||||
src="https://demos.creative-tim.com/material-dashboard/assets/img/team-2.jpg"
|
||||
alt="item-1"
|
||||
size="sm"
|
||||
variant="circular"
|
||||
/>
|
||||
<div>
|
||||
<Typography
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="mb-1 font-normal"
|
||||
>
|
||||
<strong>New message</strong> from Laur
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="flex items-center gap-1 text-xs font-normal opacity-60"
|
||||
>
|
||||
<ClockIcon className="h-3.5 w-3.5" /> 13 minutes ago
|
||||
</Typography>
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem className="flex items-center gap-4">
|
||||
<Avatar
|
||||
src="https://demos.creative-tim.com/material-dashboard/assets/img/small-logos/logo-spotify.svg"
|
||||
alt="item-1"
|
||||
size="sm"
|
||||
variant="circular"
|
||||
/>
|
||||
<div>
|
||||
<Typography
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="mb-1 font-normal"
|
||||
>
|
||||
<strong>New album</strong> by Travis Scott
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="flex items-center gap-1 text-xs font-normal opacity-60"
|
||||
>
|
||||
<ClockIcon className="h-3.5 w-3.5" /> 1 day ago
|
||||
</Typography>
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem className="flex items-center gap-4">
|
||||
<div className="grid h-9 w-9 place-items-center rounded-full bg-gradient-to-tr from-blue-gray-800 to-blue-gray-900">
|
||||
<CreditCardIcon className="h-4 w-4 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<Typography
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="mb-1 font-normal"
|
||||
>
|
||||
Payment successfully completed
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="flex items-center gap-1 text-xs font-normal opacity-60"
|
||||
>
|
||||
<ClockIcon className="h-3.5 w-3.5" /> 2 days ago
|
||||
</Typography>
|
||||
</div>
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu> */}
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="blue-gray"
|
||||
onClick={() => setOpenConfigurator(dispatch, true)}
|
||||
>
|
||||
<Cog6ToothIcon className="h-5 w-5 text-blue-gray-500 " />
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
</Navbar>
|
||||
);
|
||||
}
|
||||
|
||||
DashboardNavbar.displayName = "/src/widgets/layout/dashboard-navbar.jsx";
|
||||
|
||||
export default DashboardNavbar;
|
||||
@@ -0,0 +1,20 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { Typography } from "@material-tailwind/react";
|
||||
import { HeartIcon } from "@heroicons/react/24/solid";
|
||||
|
||||
export function Footer() {
|
||||
const year = new Date().getFullYear();
|
||||
|
||||
return (
|
||||
<footer>
|
||||
<div className="flex w-full flex-wrap items-center justify-center md:justify-end">
|
||||
<Typography variant="small" className="mt-1 text-xs text-stormGrey-500 block antialiased font-sans">
|
||||
StackPulse: © {year} by Michael Böhmländer
|
||||
</Typography>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
Footer.displayName = "/src/widgets/layout/footer.jsx";
|
||||
export default Footer;
|
||||
@@ -0,0 +1,5 @@
|
||||
export * from "@/widgets/layout/sidenav";
|
||||
export * from "@/widgets/layout/dashboard-navbar";
|
||||
export * from "@/widgets/layout/configurator";
|
||||
export * from "@/widgets/layout/footer";
|
||||
export * from "@/widgets/layout/navbar";
|
||||
@@ -0,0 +1,107 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { Link } from "react-router-dom";
|
||||
import {
|
||||
Navbar as MTNavbar,
|
||||
Collapse,
|
||||
Typography,
|
||||
Button,
|
||||
IconButton,
|
||||
} from "@material-tailwind/react";
|
||||
import { Bars3Icon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
export function Navbar({ brandName, routes, action }) {
|
||||
const [openNav, setOpenNav] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
() => window.innerWidth >= 960 && setOpenNav(false)
|
||||
);
|
||||
}, []);
|
||||
|
||||
const navList = (
|
||||
<ul className="mb-4 mt-2 flex flex-col gap-2 lg:mb-0 lg:mt-0 lg:flex-row lg:items-center lg:gap-6">
|
||||
{routes.map(({ name, path, icon }) => (
|
||||
<Typography
|
||||
key={name}
|
||||
as="li"
|
||||
variant="small"
|
||||
color="blue-gray"
|
||||
className="capitalize"
|
||||
>
|
||||
<Link to={path} className="flex items-center gap-1 p-1 font-normal">
|
||||
{icon &&
|
||||
React.createElement(icon, {
|
||||
className: "w-[18px] h-[18px] opacity-50 mr-1",
|
||||
})}
|
||||
{name}
|
||||
</Link>
|
||||
</Typography>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
|
||||
return (
|
||||
<MTNavbar className="p-3">
|
||||
<div className="container mx-auto flex items-center justify-between text-blue-gray-900">
|
||||
<Link to="/">
|
||||
<Typography
|
||||
variant="small"
|
||||
className="mr-4 ml-2 cursor-pointer py-1.5 font-bold"
|
||||
>
|
||||
{brandName}
|
||||
</Typography>
|
||||
</Link>
|
||||
<div className="hidden lg:block">{navList}</div>
|
||||
{React.cloneElement(action, {
|
||||
className: "hidden lg:inline-block",
|
||||
})}
|
||||
<IconButton
|
||||
variant="text"
|
||||
size="sm"
|
||||
className="hml-auto text-inherit hover:bg-transparent focus:bg-transparent active:bg-transparent lg:hidden"
|
||||
onClick={() => setOpenNav(!openNav)}
|
||||
>
|
||||
{openNav ? (
|
||||
<XMarkIcon strokeWidth={2} className="h-6 w-6" />
|
||||
) : (
|
||||
<Bars3Icon strokeWidth={2} className="h-6 w-6" />
|
||||
)}
|
||||
</IconButton>
|
||||
</div>
|
||||
<Collapse open={openNav}>
|
||||
<div className="container mx-auto">
|
||||
{navList}
|
||||
{React.cloneElement(action, {
|
||||
className: "w-full block lg:hidden",
|
||||
})}
|
||||
</div>
|
||||
</Collapse>
|
||||
</MTNavbar>
|
||||
);
|
||||
}
|
||||
|
||||
Navbar.defaultProps = {
|
||||
brandName: "Material Tailwind React",
|
||||
action: (
|
||||
<a
|
||||
href="https://www.creative-tim.com/product/material-tailwind-dashboard-react"
|
||||
target="_blank"
|
||||
>
|
||||
<Button variant="gradient" size="sm" fullWidth>
|
||||
free download
|
||||
</Button>
|
||||
</a>
|
||||
),
|
||||
};
|
||||
|
||||
Navbar.propTypes = {
|
||||
brandName: PropTypes.string,
|
||||
routes: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
action: PropTypes.node,
|
||||
};
|
||||
|
||||
Navbar.displayName = "/src/widgets/layout/navbar.jsx";
|
||||
|
||||
export default Navbar;
|
||||
@@ -0,0 +1,102 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { Link, NavLink } from "react-router-dom";
|
||||
import { XMarkIcon } from "@heroicons/react/24/outline";
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
IconButton,
|
||||
Typography,
|
||||
} from "@material-tailwind/react";
|
||||
import { useMaterialTailwindController, setOpenSidenav } from "@/components";
|
||||
import logo from "@/assets/images/stackpulse.png";
|
||||
|
||||
export function Sidenav({ brandImg, brandName, routes }) {
|
||||
const [controller, dispatch] = useMaterialTailwindController();
|
||||
const { sidenavColor, sidenavType, openSidenav } = controller;
|
||||
const sidenavTypes = {
|
||||
dark: "bg-gradient-to-br from-gray-800 to-gray-900",
|
||||
white: "bg-white shadow-sm",
|
||||
transparent: "bg-transparent",
|
||||
};
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={`${sidenavTypes[sidenavType]} ${openSidenav ? "translate-x-0" : "-translate-x-80"
|
||||
} fixed inset-0 z-50 my-4 ml-4 h-[calc(100vh-32px)] w-72 rounded-xl transition-transform duration-300 xl:translate-x-0 border border-blue-gray-100`}
|
||||
>
|
||||
<div className="relative py-6 px-8 text-right">
|
||||
<img src={logo} alt="StackPulse" className="w-auto" /><span className="mt-1 text-xs text-stormGrey-500 block antialiased font-sans">v0.4</span>
|
||||
|
||||
<IconButton
|
||||
variant="text"
|
||||
size="sm"
|
||||
ripple={false}
|
||||
className="absolute right-0 top-0 grid rounded-br-none rounded-tl-none"
|
||||
onClick={() => setOpenSidenav(dispatch, false)}
|
||||
>
|
||||
<XMarkIcon strokeWidth={2.5} className="h-5 w-5 text-black" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="m-4">
|
||||
{routes.map(({ layout, title, pages }, key) => (
|
||||
<ul key={key} className="mb-4 flex flex-col gap-1">
|
||||
{title && (
|
||||
<li className="mx-3.5 mt-4 mb-2">
|
||||
<Typography
|
||||
variant="small"
|
||||
color={sidenavType === "dark" ? "white" : "blue-gray"}
|
||||
className="font-black uppercase opacity-75"
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
</li>
|
||||
)}
|
||||
{pages.map(({ icon, name, path }) => (
|
||||
<li key={name}>
|
||||
<NavLink to={`/${layout}${path}`}>
|
||||
{({ isActive }) => (
|
||||
<Button
|
||||
variant={isActive ? "gradient" : "text"}
|
||||
color={
|
||||
isActive
|
||||
? sidenavColor
|
||||
: sidenavType === "dark"
|
||||
? "white"
|
||||
: "blue-gray"
|
||||
}
|
||||
className="flex items-center gap-4 px-4 capitalize"
|
||||
fullWidth
|
||||
>
|
||||
{icon}
|
||||
<Typography
|
||||
color="inherit"
|
||||
className="font-medium capitalize"
|
||||
>
|
||||
{name}
|
||||
</Typography>
|
||||
</Button>
|
||||
)}
|
||||
</NavLink>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
))}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
Sidenav.defaultProps = {
|
||||
brandImg: "/img/logo-ct.png",
|
||||
brandName: "Material Tailwind React",
|
||||
};
|
||||
|
||||
Sidenav.propTypes = {
|
||||
brandImg: PropTypes.string,
|
||||
brandName: PropTypes.string,
|
||||
routes: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
};
|
||||
|
||||
Sidenav.displayName = "/src/widgets/layout/sidnave.jsx";
|
||||
|
||||
export default Sidenav;
|
||||
@@ -0,0 +1,38 @@
|
||||
const withMT = require("@material-tailwind/react/utils/withMT");
|
||||
const colors = require("tailwindcss/colors");
|
||||
|
||||
module.exports = withMT({
|
||||
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
sky: colors.sky,
|
||||
green: colors.green,
|
||||
slate: colors.slate,
|
||||
orange: colors.orange, // falls du z. B. text-orange-300 brauchst
|
||||
auroraTeal: {50:'#f0fafb',100:'#e0f5f7',200:'#c3ecef',300:'#9de0e4',400:'#6ad3d8',500:'#38c6cc',600:'#2aa9b0',700:'#1f8d94',800:'#166e76',900:'#0c4f58'},
|
||||
sunsetCoral: {50:'#fff6f5',100:'#ffece9',200:'#ffd7d3',300:'#ffb8b5',400:'#ff9189',500:'#ff6a5d',600:'#e65048',700:'#b93d38',800:'#8a2c28',900:'#5c1c1a'},
|
||||
lavenderSmoke: {50:'#faf8fc',100:'#f5f1f9',200:'#ece2f3',300:'#dac4e6',400:'#b88acf',500:'#9670b8',600:'#7a5894',700:'#5d4373',800:'#412f52',900:'#291e38'},
|
||||
mossGreen: {50:'#f5faf2',100:'#ebf5e5',200:'#d9ebca',300:'#b8d99e',400:'#8cc56f',500:'#60b240',600:'#4d8f33',700:'#3b6b27',800:'#2a491d',900:'#1c3012'},
|
||||
deepOceanBlue: {50:'#f4faff',100:'#e9f5ff',200:'#cfe6ff',300:'#add1ff',400:'#7ab9ff',500:'#479fff',600:'#3c86e6',700:'#305eaf',800:'#23437f',900:'#162a50'},
|
||||
warmAmberGlow: {50:'#fff9f2',100:'#fff3e5',200:'#ffe6cc',300:'#ffcc99',400:'#ffad4d',500:'#ff8f00',600:'#e67600',700:'#b35a00',800:'#804000',900:'#4d2600'},
|
||||
peachMist: {50:'#fff8f7',100:'#fff0ed',200:'#ffe1db',300:'#ffc2b7',400:'#ff9a87',500:'#ff7257',600:'#e65f4b',700:'#b34938',800:'#803622',900:'#4d230f'},
|
||||
slatePurple: {50:'#f7f5fa',100:'#efe9f5',200:'#ded1ea',300:'#bdb3d5',400:'#9584b5',500:'#6d5795',600:'#5c4a7c',700:'#473861',800:'#322648',900:'#1f1530'},
|
||||
mintTea: {50:'#f2fcfa',100:'#e5f9f6',200:'#ccefee',300:'#99dfdc',400:'#66cfc9',500:'#33bfb6',600:'#2aa395',700:'#228174',800:'#195953',900:'#103330'},
|
||||
copperRust: {50:'#faf7f6',100:'#f5efee',200:'#ebe0dc',300:'#d6c1b8',400:'#b28a86',500:'#8d4d55',600:'#7a444b',700:'#5f3338',800:'#442426',900:'#2d1718'},
|
||||
// Neue 10
|
||||
arcticBlue: {50:'#f2f9fd',100:'#e6f3fb',200:'#cce6f7',300:'#99ceef',400:'#66b6e7',500:'#339ede',600:'#1f86c3',700:'#16699b',800:'#0f4b6f',900:'#082d43'},
|
||||
roseQuartz: {50:'#fdf7f9',100:'#faeff3',200:'#f5dfe6',300:'#ecbfd0',400:'#e08dad',500:'#d45b89',600:'#b94771',700:'#8e3556',800:'#63233b',900:'#391324'},
|
||||
citrusPunch: {50:'#fffdf6',100:'#fffbe9',200:'#fff5cc',300:'#ffeb99',400:'#ffe066',500:'#ffd633',600:'#e6bd00',700:'#b39300',800:'#806900',900:'#4d3f00'},
|
||||
midnightPlum: {50:'#faf7fb',100:'#f4ecf6',200:'#e4cfee',300:'#cba0de',400:'#a869cc',500:'#8431b9',600:'#6d299b',700:'#521f74',800:'#38154d',900:'#1f0b28'},
|
||||
sandstone: {50:'#fbf9f7',100:'#f6f2ee',200:'#ece3da',300:'#d8c6b3',400:'#c0a27f',500:'#a87e4b',600:'#906a3e',700:'#6b4f2f',800:'#47341f',900:'#241a10'},
|
||||
emeraldMist: {50:'#f3faf7',100:'#e7f6ef',200:'#ccecdc',300:'#9ddabf',400:'#6ec8a3',500:'#3fb586',600:'#359771',700:'#2a765a',800:'#1f5442',900:'#13332a'},
|
||||
velvetRed: {50:'#fdf7f7',100:'#faeeee',200:'#f4d6d6',300:'#e7a8a8',400:'#d56666',500:'#c32424',600:'#a61e1e',700:'#801717',800:'#590f0f',900:'#330808'},
|
||||
stormGrey: {50:'#f7f8fa',100:'#eef0f3',200:'#d9dce2',300:'#b6bbc8',400:'#8b91a4',500:'#606780',600:'#4f556b',700:'#3e4456',800:'#2c313f',900:'#1b1e29'},
|
||||
neonLime: {50:'#f7ffe6',100:'#eeffc9',200:'#dbff96',300:'#c2ff52',400:'#a8ff0e',500:'#8de600',600:'#74bf00',700:'#5b9900',800:'#426f00',900:'#294600'},
|
||||
skyMauve: {50:'#faf8fc',100:'#f4f0f9',200:'#e5dbf2',300:'#c9b2e6',400:'#a27dd4',500:'#7b48c2',600:'#633aa0',700:'#4b2b7c',800:'#341d58',900:'#1e1035'},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
});
|
||||
@@ -1,8 +1,11 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: [{ find: "@", replacement: "/src" }],
|
||||
},
|
||||
server: {
|
||||
host: true, // Hört auf allen Netzwerk-Interfaces, kein localhost notwendig
|
||||
port: 5173, // optional, Standardport für Vite
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>StackPulse</title>
|
||||
<link rel="stylesheet" href="/src/index.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "stackpulse-frontend",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "1.7.5",
|
||||
"socket.io-client": "4.8.1",
|
||||
"@heroicons/react": "2.0.18",
|
||||
"@material-tailwind/react": "2.1.4",
|
||||
"apexcharts": "3.44.0",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "18.2.0",
|
||||
"react-apexcharts": "1.4.1",
|
||||
"react-dom": "18.2.0",
|
||||
"react-router-dom": "6.17.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "18.2.31",
|
||||
"@types/react-dom": "18.2.14",
|
||||
"@vitejs/plugin-react": "4.1.0",
|
||||
"autoprefixer": "10.4.16",
|
||||
"postcss": "8.4.31",
|
||||
"prettier": "3.0.3",
|
||||
"prettier-plugin-tailwindcss": "0.5.6",
|
||||
"tailwindcss": "3.3.4",
|
||||
"vite": "4.5.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import React from "react";
|
||||
import { NavLink, Route, Routes } from "react-router-dom";
|
||||
import Stacks from "./Stacks.jsx";
|
||||
import Logs from "./Logs.jsx";
|
||||
import Maintenance from "./Maintenance.jsx";
|
||||
import logo from "./assets/images/stackpulse.png";
|
||||
import { useMaintenance } from "./context/MaintenanceContext.jsx";
|
||||
|
||||
const navLinkBase =
|
||||
"px-4 py-2 rounded-md font-medium transition-colors duration-150";
|
||||
|
||||
const getNavClass = ({ isActive }) =>
|
||||
`${navLinkBase} ${isActive ? "bg-purple-600 text-white" : "text-gray-300 hover:bg-gray-700"}`;
|
||||
|
||||
export default function App() {
|
||||
const { maintenance, update } = useMaintenance();
|
||||
const maintenanceActive = Boolean(maintenance?.active);
|
||||
const maintenanceLabel = maintenance?.message || (update?.running ? "Portainer-Update läuft" : "Wartungsmodus aktiv");
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-900 text-white">
|
||||
<header className="bg-gray-800 shadow-md">
|
||||
<div className="max-w-6xl mx-auto px-6 py-6">
|
||||
<div className="flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
|
||||
<div className="flex flex-col items-end gap-1">
|
||||
<span className="text-xs text-gray-500">v0.3</span>
|
||||
{maintenanceActive && (
|
||||
<span className="flex items-center gap-1 text-xs text-amber-300">
|
||||
<span className="h-2 w-2 animate-pulse rounded-full bg-amber-400" />
|
||||
{maintenanceLabel}
|
||||
</span>
|
||||
)}
|
||||
<img src={logo} alt="StackPulse" className="h-10 w-auto" />
|
||||
</div>
|
||||
<nav className="flex gap-2 items-end">
|
||||
<NavLink to="/" end className={getNavClass}>
|
||||
Stacks
|
||||
</NavLink>
|
||||
<NavLink to="/maintenance" className={getNavClass}>
|
||||
<span className="flex items-center gap-2">
|
||||
Wartung
|
||||
{maintenanceActive && (
|
||||
<span className="h-2 w-2 animate-pulse rounded-full bg-amber-400" />
|
||||
)}
|
||||
</span>
|
||||
</NavLink>
|
||||
|
||||
<NavLink to="/logs" className={getNavClass}>
|
||||
Logs
|
||||
</NavLink>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main className="max-w-6xl mx-auto px-6 py-6">
|
||||
<Routes>
|
||||
<Route path="/" element={<Stacks />} />
|
||||
<Route path="/maintenance" element={<Maintenance />} />
|
||||
<Route path="/logs" element={<Logs />} />
|
||||
<Route path="*" element={<Stacks />} />
|
||||
</Routes>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -807,12 +807,12 @@ export default function Logs() {
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap items-center justify-end gap-3">
|
||||
<button
|
||||
<Button
|
||||
onClick={handleResetFilters}
|
||||
className="rounded-md border border-gray-600 px-4 py-2 text-gray-200 transition hover:bg-gray-700"
|
||||
>
|
||||
Zurücksetzen
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -532,7 +532,7 @@ export default function Maintenance() {
|
||||
{maintenanceError}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Beginn Portainer Update */}
|
||||
<div className="rounded-xl border border-gray-700 bg-gray-800/60 p-6 shadow-lg">
|
||||
<div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
||||
<div>
|
||||
@@ -918,6 +918,7 @@ export default function Maintenance() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Ende Portainer Update */}
|
||||
<div className="rounded-xl border border-gray-700 bg-gray-800/60 p-6 shadow-lg">
|
||||
<div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
||||
<div>
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,121 @@
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
const ToastContext = createContext(null);
|
||||
|
||||
const VARIANT_STYLES = {
|
||||
success: {
|
||||
container: "border-green-500/80 bg-green-950/90 text-green-100",
|
||||
accent: "bg-green-400"
|
||||
},
|
||||
warning: {
|
||||
container: "border-yellow-500/80 bg-yellow-950/90 text-yellow-100",
|
||||
accent: "bg-yellow-400"
|
||||
},
|
||||
error: {
|
||||
container: "border-red-500/80 bg-red-950/90 text-red-100",
|
||||
accent: "bg-red-400"
|
||||
},
|
||||
info: {
|
||||
container: "border-sky-500/60 bg-sky-950/90 text-sky-100",
|
||||
accent: "bg-sky-400"
|
||||
}
|
||||
};
|
||||
|
||||
const DEFAULT_DURATION = 6000;
|
||||
|
||||
export default function ToastProvider({ children }) {
|
||||
const [toasts, setToasts] = useState([]);
|
||||
const timeoutsRef = useRef(new Map());
|
||||
|
||||
const dismissToast = useCallback((id) => {
|
||||
setToasts((prev) => prev.filter((toast) => toast.id !== id));
|
||||
|
||||
const handle = timeoutsRef.current.get(id);
|
||||
if (handle && typeof window !== "undefined") {
|
||||
window.clearTimeout(handle);
|
||||
}
|
||||
timeoutsRef.current.delete(id);
|
||||
}, []);
|
||||
|
||||
const showToast = useCallback(({ id, title, description, variant = "info", duration = DEFAULT_DURATION } = {}) => {
|
||||
const toastId = id ?? `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
||||
const normalizedVariant = VARIANT_STYLES[variant] ? variant : "info";
|
||||
|
||||
setToasts((prev) => {
|
||||
const withoutExisting = prev.filter((toast) => toast.id !== toastId);
|
||||
return [
|
||||
...withoutExisting,
|
||||
{
|
||||
id: toastId,
|
||||
title,
|
||||
description,
|
||||
variant: normalizedVariant
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
if (duration !== null && duration !== Infinity && typeof window !== "undefined") {
|
||||
const timeoutHandle = window.setTimeout(() => {
|
||||
dismissToast(toastId);
|
||||
}, duration);
|
||||
|
||||
const existingHandle = timeoutsRef.current.get(toastId);
|
||||
if (existingHandle) {
|
||||
window.clearTimeout(existingHandle);
|
||||
}
|
||||
timeoutsRef.current.set(toastId, timeoutHandle);
|
||||
}
|
||||
|
||||
return toastId;
|
||||
}, [dismissToast]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (typeof window === "undefined") return;
|
||||
timeoutsRef.current.forEach((handle) => window.clearTimeout(handle));
|
||||
timeoutsRef.current.clear();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const contextValue = useMemo(() => ({ showToast, dismissToast }), [showToast, dismissToast]);
|
||||
|
||||
return (
|
||||
<ToastContext.Provider value={contextValue}>
|
||||
{children}
|
||||
<div className="pointer-events-none fixed right-4 top-4 z-50 flex w-80 max-w-full flex-col gap-3">
|
||||
{toasts.map((toast) => {
|
||||
const styles = VARIANT_STYLES[toast.variant] ?? VARIANT_STYLES.info;
|
||||
return (
|
||||
<div
|
||||
key={toast.id}
|
||||
className={`pointer-events-auto overflow-hidden rounded-lg border px-4 py-3 shadow-xl backdrop-blur ${styles.container}`}
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
<span className={`mt-1 h-2 flex-shrink-0 w-2 rounded-full ${styles.accent}`}></span>
|
||||
<div className="flex-1">
|
||||
{toast.title && <p className="text-sm font-semibold">{toast.title}</p>}
|
||||
{toast.description && <p className="mt-1 text-sm leading-snug text-white/80">{toast.description}</p>}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => dismissToast(toast.id)}
|
||||
className="ml-2 rounded-md p-1 text-xs uppercase tracking-wide text-white/60 transition hover:text-white/90"
|
||||
>
|
||||
Schließen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</ToastContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useToast() {
|
||||
const context = useContext(ToastContext);
|
||||
if (!context) {
|
||||
throw new Error('useToast must be used within a ToastProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import App from "./App.jsx";
|
||||
import ToastProvider from "./components/ToastProvider.jsx";
|
||||
import MaintenanceProvider from "./context/MaintenanceContext.jsx";
|
||||
import './index.css'; // Tailwind CSS
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<BrowserRouter>
|
||||
<MaintenanceProvider>
|
||||
<ToastProvider>
|
||||
<App />
|
||||
</ToastProvider>
|
||||
</MaintenanceProvider>
|
||||
</BrowserRouter>
|
||||
</React.StrictMode>
|
||||
);
|
||||
File renamed without changes.
@@ -0,0 +1,21 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
server: {
|
||||
host: true, // Hört auf allen Netzwerk-Interfaces, kein localhost notwendig
|
||||
port: 5173, // optional, Standardport für Vite
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://127.0.0.1:4001', // Backend lokal auf Port 4001
|
||||
changeOrigin: true
|
||||
},
|
||||
'/socket.io': {
|
||||
target: 'http://127.0.0.1:4001', // WebSocket-Verbindungen über Proxy weiterleiten
|
||||
ws: true,
|
||||
changeOrigin: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user