Compare commits

...

45 Commits

Author SHA1 Message Date
OlgunR
a620e646f0 feat(overview): update envelope statistics and localization in AnalyticsWidgetSummary 2025-12-11 16:20:58 +01:00
OlgunR
88c376262a feat(langs): remove French language option from language data 2025-12-11 15:54:47 +01:00
OlgunR
369c50f32c feat(overview): update AnalyticsWidgetSummary title and icon for clarity 2025-12-11 15:52:36 +01:00
OlgunR
e25a77335b feat(nav): comment out NavUpgrade component in NavContent for future reference 2025-12-11 15:33:02 +01:00
OlgunR
85dc9a20af feat(layout): enhance mobile navigation with title and improved layout structure 2025-12-10 16:25:55 +01:00
OlgunR
2743913786 feat(dashboard): refine layout and navigation behavior with improved transition effects 2025-12-10 15:43:38 +01:00
OlgunR
58fb4f2849 feat(nav): update NavDesktop and NavMobile styles for improved consistency and visibility 2025-12-10 15:38:34 +01:00
OlgunR
a2673216c9 feat(dashboard): update NavMobile component to use onToggle for menu button and adjust layout styles for responsiveness 2025-12-10 15:23:13 +01:00
OlgunR
a01bde914a feat(overview): add file statistics fetching and display in analytics view 2025-12-10 15:00:55 +01:00
OlgunR
214afea43d feat(app): update scroll-to-top button colors for improved visibility 2025-12-10 14:26:05 +01:00
OlgunR
10e1c5a971 feat(dashboard): enhance layout styles and improve header navigation appearance 2025-12-10 14:24:59 +01:00
OlgunR
f2b6d04ceb feat(app): implement scroll-to-top button with visibility toggle on scroll 2025-12-10 13:59:33 +01:00
OlgunR
cb4c61d1e4 Add new icons for file, organization, signature, task, and flow functionalities
- Introduced DD_fileFLOW_ICON.ico to represent file flow.
- Added DD_orgFLOW_ICON.ico for organizational flow representation.
- Included DD_signFLOW_ICON.ico for signature flow functionality.
- Implemented DD_taskFLOW_ICON.ico to depict task flow.
- All icons are in ICO format and located in the dd-icons directory.
2025-11-25 11:21:51 +01:00
OlgunR
a62902b538 Refactor code structure for improved readability and maintainability 2025-11-25 10:13:40 +01:00
OlgunR
9c3fc8f83a refactor(nav-config): correct icon for ChartFlow to use analytics icon 2025-11-25 10:10:54 +01:00
OlgunR
cfbdda6e02 feat(charts): add new ChartFlow page and analytics components for enhanced dashboard insights 2025-11-24 17:18:06 +01:00
OlgunR
df144ae357 refactor(nav-config): reorganize navigation items and update titles for clarity 2025-11-24 15:51:35 +01:00
OlgunR
cb28e90241 refactor(nav-config): correct 'Product' title to 'Products' and restore commented-out nav items 2025-11-24 14:49:55 +01:00
OlgunR
df84ad4afd refactor(dashboard): correct component import and usage in DashboardPage 2025-11-24 14:49:10 +01:00
OlgunR
de019d5825 refactor(routes): update default route to render DashboardPage instead of ProductsPage 2025-11-24 14:45:28 +01:00
OlgunR
a07a911ea9 fix: update borderRadius type casting for consistency across components 2025-11-24 12:00:39 +01:00
364c67f3ad feat(document.json): convert mock data to json 2025-07-16 15:40:14 +02:00
2adcc217af feat: Unterstützung von asynchroner Dateneingabe für DocFullView Komponente
- DocFullView aktualisiert, um Daten als Uint8Array oder Promise<Uint8Array> zu akzeptieren
- Asynchrones Handling in useEffect hinzugefügt, um Daten vor der Erstellung der Objekt-URL aufzulösen
- Verbesserte Bereinigungslogik, um die Objekt-URL richtig zu widerrufen
- Geänderte Format-Prop ist nun erforderlich
2025-07-16 15:26:51 +02:00
8c7e18637a refactor(document-service): Umbenennung der Methode getDocuments in get für Konsistenz
- Die Methode `getDocuments` in `DocService` wurde in `get` umbenannt, um die Verwendung zu vereinfachen und die Konsistenz der Namensgebung bei allen Abfragemethoden (`getDocumentById`, `getDocumentByName`, `getDocumentByAttributes`) zu verbessern.
 - Keine Änderungen an der Funktionalität oder dem externen Verhalten.
2025-07-16 14:51:28 +02:00
a88238f209 refactor(data): move base64 decoding to _genFile and remove inline data field
- Removed inline base64 decoding (`data` field) from `_documents` definitions
- Introduced `_genFile(name)` utility to generate Uint8Array from file name
- Simplified `_documents` by eliminating direct `data` property population
2025-07-16 14:43:47 +02:00
a34270cfc3 refactor(doc): encapsulate document query functions into DocService class 2025-07-16 13:45:46 +02:00
c022b96a12 feat(document-service): Unterstützung für die Abfrage von Dokumenten nach Attributen hinzugefügt
- Erforderlich für `DocAttribute.serilizedValue`.
- Erweitert `DocQuery` mit optionalem `attributes` Feld.
- Aktualisiert `getDocuments` um nach Attribut-Schlüssel-Wert-Paaren zu filtern.
- Hilfsfunktion `getDocumentByAttributes` hinzugefügt.
2025-07-16 13:32:57 +02:00
bbb55e9746 feat(filters): Entprellen von onChange-Callbacks in TextFilter-, IntFilter- und DecimalFilter-Komponenten, um schnelles Auslösen zu reduzieren 2025-07-16 11:53:57 +02:00
d82e12759e feat(doc-search-view); add useEffect to follow attributes 2025-07-16 11:07:27 +02:00
3cef34bd1e feat(doc-search): Hinzufügen von Attributstatusverwaltung und Eingabewertbindung für Filter 2025-07-16 11:03:07 +02:00
1fbcdd82c8 refactor(doc-search-view): updated to initalize the documents in the component 2025-07-15 16:58:48 +02:00
f58fa0dd80 feat: add optional onChange handler to TextFilter component
- Extended TextFilterProps to include an optional onChange callback
- Passed input value to onChange when TextField changes
- Enables consumers to handle input updates externally
2025-07-15 15:32:01 +02:00
8a43e88f24 refactor(json-viewer): remove console.log 2025-07-15 14:37:48 +02:00
cfadae4df3 feat(json-viewer): create to view json data 2025-07-15 12:37:48 +02:00
4e1ab7e9c2 refactor(_data.ts): Attributliste zu Dokumenten hinzufügen 2025-07-14 15:41:45 +02:00
9a03c3ef85 feat(_mock): add typed attributes to document mocks and extend Attribute types 2025-07-14 14:59:11 +02:00
d5d82a5a1e feat(doc): Unterstützung für benutzerdefinierte Dokumentattribute hinzufügen 2025-07-14 13:56:36 +02:00
8d7615fb37 refactor(./api): umbenennen in ./services 2025-07-14 13:40:00 +02:00
1af2ee3890 feat: localize fallback message in DocFullView for unsupported file types
Replaced English fallback message with German translation when a file type cannot be previewed. Message updated to:
"Dieser Dateityp kann nicht angezeigt werden. Sie können es unten herunterladen:"
2025-07-14 13:28:41 +02:00
8bfcd65ad1 refactor(Filter): umbenennen in Attribut 2025-07-14 11:42:29 +02:00
75ecbba71d fix(doc-full-view): Hintergrundfarbe für nicht unterstützte Formate festlegen (Fallback)
Es wurde ein hellgrauer Hintergrund zum Modal hinzugefügt, wenn nicht unterstützte Dateiformate dargestellt werden, um die visuelle Klarheit und die Benutzererfahrung zu verbessern.
2025-07-14 11:11:02 +02:00
1a55bd7748 feat: Vorschau-Modal für Dokument-Dateien mit Unterstützung für mehrere Formate
- Prop `format` zu DocFullView hinzugefügt, um den Dateityp zu spezifizieren
- Dynamische Blob-Generierung mit korrektem MIME-Typ implementiert
- Unterstützt Inline-Vorschau für Formate wie PDF, HTML, Bilder, etc.
- Fallback zum Download-Link für nicht unterstützte Dateitypen
- Ungenutzte Statusfelder wurden entfernt und der modale Inhalt vereinfacht
2025-07-14 10:53:09 +02:00
3e7a22f9e2 feat(document-service): add type-safe file extension handling with FileFormat union
- Introduced `FileFormat` union type to restrict valid document extensions.
- Added `validExtensions` array for strict extension checking in `Doc.extension` getter.
- Ensured `Doc.iconSrc` reflects only recognized file types or defaults to 'unknown'.
- Improved type safety and consistency in extension handling.
2025-07-14 10:28:11 +02:00
49667d7fe9 feat(doc): Modale Vollansicht des Dokuments hinzufügen und Öffnen bei Kartenklick ermöglichen 2025-07-14 10:04:06 +02:00
b15b4dc3b1 feat(doc-item): add hover animation to DocItem card
- Added default styling with hover transition
- Preserves user-defined `sx` if passed
2025-07-14 09:47:53 +02:00
50 changed files with 2685 additions and 706 deletions

View File

@@ -10,17 +10,18 @@
"dependencies": {
"@emotion/cache": "^11.14.0",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@fontsource-variable/dm-sans": "^5.2.5",
"@fontsource/barlow": "^5.2.5",
"@iconify/react": "^5.2.1",
"@mui/icons-material": "^7.2.0",
"@mui/icons-material": "^7.3.5",
"@mui/lab": "^7.0.0-beta.10",
"@mui/material": "^7.0.1",
"@mui/material": "^7.3.5",
"@mui/x-date-pickers": "^8.7.0",
"apexcharts": "^4.5.0",
"dayjs": "^1.11.13",
"es-toolkit": "^1.34.1",
"lodash.debounce": "^4.0.8",
"minimal-shared": "^1.0.7",
"react": "^19.1.0",
"react-apexcharts": "^1.7.0",
@@ -30,6 +31,7 @@
},
"devDependencies": {
"@eslint/js": "^9.23.0",
"@types/lodash.debounce": "^4.0.9",
"@types/node": "^22.14.0",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.1",
@@ -130,9 +132,9 @@
}
},
"node_modules/@babel/runtime": {
"version": "7.27.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
"integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
"version": "7.28.4",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -284,6 +286,7 @@
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -323,10 +326,11 @@
"license": "MIT"
},
"node_modules/@emotion/styled": {
"version": "11.14.0",
"resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz",
"integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==",
"version": "11.14.1",
"resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz",
"integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -798,9 +802,9 @@
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz",
"integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==",
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -840,13 +844,13 @@
}
},
"node_modules/@eslint/config-array": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz",
"integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
"integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@eslint/object-schema": "^2.1.6",
"@eslint/object-schema": "^2.1.7",
"debug": "^4.3.1",
"minimatch": "^3.1.2"
},
@@ -855,9 +859,9 @@
}
},
"node_modules/@eslint/config-array/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -879,19 +883,22 @@
}
},
"node_modules/@eslint/config-helpers": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz",
"integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==",
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
"integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@eslint/core": "^0.17.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/core": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
"integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==",
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
"integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -926,9 +933,9 @@
}
},
"node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -963,19 +970,22 @@
}
},
"node_modules/@eslint/js": {
"version": "9.23.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz",
"integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==",
"version": "9.39.1",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz",
"integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://eslint.org/donate"
}
},
"node_modules/@eslint/object-schema": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
"integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
"integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -983,32 +993,19 @@
}
},
"node_modules/@eslint/plugin-kit": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz",
"integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==",
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
"integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@eslint/core": "^0.13.0",
"@eslint/core": "^0.17.0",
"levn": "^0.4.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz",
"integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@types/json-schema": "^7.0.15"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@fontsource-variable/dm-sans": {
"version": "5.2.5",
"resolved": "https://registry.npmjs.org/@fontsource-variable/dm-sans/-/dm-sans-5.2.5.tgz",
@@ -1163,9 +1160,9 @@
}
},
"node_modules/@mui/core-downloads-tracker": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.2.0.tgz",
"integrity": "sha512-d49s7kEgI5iX40xb2YPazANvo7Bx0BLg/MNRwv+7BVpZUzXj1DaVCKlQTDex3gy/0jsCb4w7AY2uH4t4AJvSog==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.5.tgz",
"integrity": "sha512-kOLwlcDPnVz2QMhiBv0OQ8le8hTCqKM9cRXlfVPL91l3RGeOsxrIhNRsUt3Xb8wb+pTVUolW+JXKym93vRKxCw==",
"license": "MIT",
"funding": {
"type": "opencollective",
@@ -1173,12 +1170,12 @@
}
},
"node_modules/@mui/icons-material": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.2.0.tgz",
"integrity": "sha512-gRCspp3pfjHQyTmSOmYw7kUQTd9Udpdan4R8EnZvqPeoAtHnPzkvjBrBqzKaoAbbBp5bGF7BcD18zZJh4nwu0A==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.5.tgz",
"integrity": "sha512-LciL1GLMZ+VlzyHAALSVAR22t8IST4LCXmljcUSx2NOutgO2XnxdIp8ilFbeNf9wpo0iUFbAuoQcB7h+HHIf3A==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.6"
"@babel/runtime": "^7.28.4"
},
"engines": {
"node": ">=14.0.0"
@@ -1188,7 +1185,7 @@
"url": "https://opencollective.com/mui-org"
},
"peerDependencies": {
"@mui/material": "^7.2.0",
"@mui/material": "^7.3.5",
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
@@ -1243,22 +1240,23 @@
}
},
"node_modules/@mui/material": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-7.2.0.tgz",
"integrity": "sha512-NTuyFNen5Z2QY+I242MDZzXnFIVIR6ERxo7vntFi9K1wCgSwvIl0HcAO2OOydKqqKApE6omRiYhpny1ZhGuH7Q==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.5.tgz",
"integrity": "sha512-8VVxFmp1GIm9PpmnQoCoYo0UWHoOrdA57tDL62vkpzEgvb/d71Wsbv4FRg7r1Gyx7PuSo0tflH34cdl/NvfHNQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.27.6",
"@mui/core-downloads-tracker": "^7.2.0",
"@mui/system": "^7.2.0",
"@mui/types": "^7.4.4",
"@mui/utils": "^7.2.0",
"@babel/runtime": "^7.28.4",
"@mui/core-downloads-tracker": "^7.3.5",
"@mui/system": "^7.3.5",
"@mui/types": "^7.4.8",
"@mui/utils": "^7.3.5",
"@popperjs/core": "^2.11.8",
"@types/react-transition-group": "^4.4.12",
"clsx": "^2.1.1",
"csstype": "^3.1.3",
"prop-types": "^15.8.1",
"react-is": "^19.1.0",
"react-is": "^19.2.0",
"react-transition-group": "^4.4.5"
},
"engines": {
@@ -1271,7 +1269,7 @@
"peerDependencies": {
"@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0",
"@mui/material-pigment-css": "^7.2.0",
"@mui/material-pigment-css": "^7.3.5",
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
@@ -1292,13 +1290,13 @@
}
},
"node_modules/@mui/private-theming": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.2.0.tgz",
"integrity": "sha512-y6N1Yt3T5RMxVFnCh6+zeSWBuQdNDm5/UlM0EAYZzZR/1u+XKJWYQmbpx4e+F+1EpkYi3Nk8KhPiQDi83M3zIw==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.5.tgz",
"integrity": "sha512-cTx584W2qrLonwhZLbEN7P5pAUu0nZblg8cLBlTrZQ4sIiw8Fbvg7GvuphQaSHxPxrCpa7FDwJKtXdbl2TSmrA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.6",
"@mui/utils": "^7.2.0",
"@babel/runtime": "^7.28.4",
"@mui/utils": "^7.3.5",
"prop-types": "^15.8.1"
},
"engines": {
@@ -1319,12 +1317,12 @@
}
},
"node_modules/@mui/styled-engine": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.2.0.tgz",
"integrity": "sha512-yq08xynbrNYcB1nBcW9Fn8/h/iniM3ewRguGJXPIAbHvxEF7Pz95kbEEOAAhwzxMX4okhzvHmk0DFuC5ayvgIQ==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.5.tgz",
"integrity": "sha512-zbsZ0uYYPndFCCPp2+V3RLcAN6+fv4C8pdwRx6OS3BwDkRCN8WBehqks7hWyF3vj1kdQLIWrpdv/5Y0jHRxYXQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.6",
"@babel/runtime": "^7.28.4",
"@emotion/cache": "^11.14.0",
"@emotion/serialize": "^1.3.3",
"@emotion/sheet": "^1.4.0",
@@ -1353,16 +1351,17 @@
}
},
"node_modules/@mui/system": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-7.2.0.tgz",
"integrity": "sha512-PG7cm/WluU6RAs+gNND2R9vDwNh+ERWxPkqTaiXQJGIFAyJ+VxhyKfzpdZNk0z0XdmBxxi9KhFOpgxjehf/O0A==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.5.tgz",
"integrity": "sha512-yPaf5+gY3v80HNkJcPi6WT+r9ebeM4eJzrREXPxMt7pNTV/1eahyODO4fbH3Qvd8irNxDFYn5RQ3idHW55rA6g==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.27.6",
"@mui/private-theming": "^7.2.0",
"@mui/styled-engine": "^7.2.0",
"@mui/types": "^7.4.4",
"@mui/utils": "^7.2.0",
"@babel/runtime": "^7.28.4",
"@mui/private-theming": "^7.3.5",
"@mui/styled-engine": "^7.3.5",
"@mui/types": "^7.4.8",
"@mui/utils": "^7.3.5",
"clsx": "^2.1.1",
"csstype": "^3.1.3",
"prop-types": "^15.8.1"
@@ -1393,12 +1392,12 @@
}
},
"node_modules/@mui/types": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.4.tgz",
"integrity": "sha512-p63yhbX52MO/ajXC7hDHJA5yjzJekvWD3q4YDLl1rSg+OXLczMYPvTuSuviPRCgRX8+E42RXz1D/dz9SxPSlWg==",
"version": "7.4.8",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.8.tgz",
"integrity": "sha512-ZNXLBjkPV6ftLCmmRCafak3XmSn8YV0tKE/ZOhzKys7TZXUiE0mZxlH8zKDo6j6TTUaDnuij68gIG+0Ucm7Xhw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.6"
"@babel/runtime": "^7.28.4"
},
"peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0"
@@ -1410,17 +1409,17 @@
}
},
"node_modules/@mui/utils": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.2.0.tgz",
"integrity": "sha512-O0i1GQL6MDzhKdy9iAu5Yr0Sz1wZjROH1o3aoztuivdCXqEeQYnEjTDiRLGuFxI9zrUbTHBwobMyQH5sNtyacw==",
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.5.tgz",
"integrity": "sha512-jisvFsEC3sgjUjcPnR4mYfhzjCDIudttSGSbe1o/IXFNu0kZuR+7vqQI0jg8qtcVZBHWrwTfvAZj9MNMumcq1g==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.6",
"@mui/types": "^7.4.4",
"@babel/runtime": "^7.28.4",
"@mui/types": "^7.4.8",
"@types/prop-types": "^15.7.15",
"clsx": "^2.1.1",
"prop-types": "^15.8.1",
"react-is": "^19.1.0"
"react-is": "^19.2.0"
},
"engines": {
"node": ">=14.0.0"
@@ -1901,6 +1900,7 @@
"resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.2.4.tgz",
"integrity": "sha512-BjJ/7vWNowlX3Z8O4ywT58DqbNRyYlkk6Yz/D13aB7hGmfQTvGX4Tkgtm/ApYlu9M7lCQi15xUEidqMUmdMYwg==",
"license": "MIT",
"peer": true,
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Fuzzyma"
@@ -1924,6 +1924,7 @@
"resolved": "https://registry.npmjs.org/@svgdotjs/svg.select.js/-/svg.select.js-4.0.2.tgz",
"integrity": "sha512-5gWdrvoQX3keo03SCmgaBbD+kFftq0F/f2bzCbNnpkkvW6tk4rl4MakORzFuNjvXPWwB4az9GwuvVxQVnjaK2g==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 14.18"
},
@@ -2168,12 +2169,6 @@
"tslib": "^2.4.0"
}
},
"node_modules/@types/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
"license": "MIT"
},
"node_modules/@types/estree": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
@@ -2195,12 +2190,30 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/lodash.debounce": {
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz",
"integrity": "sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/node": {
"version": "22.14.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz",
"integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -2222,6 +2235,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.0.tgz",
"integrity": "sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w==",
"license": "MIT",
"peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
@@ -2251,6 +2265,7 @@
"integrity": "sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.29.0",
@@ -2281,6 +2296,7 @@
"integrity": "sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.29.0",
"@typescript-eslint/types": "8.29.0",
@@ -2658,11 +2674,12 @@
"license": "MIT"
},
"node_modules/acorn": {
"version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2731,6 +2748,7 @@
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-4.5.0.tgz",
"integrity": "sha512-E7ZkrVqPNBUWy/Rmg8DEIqHNBmElzICE/oxOX5Ekvs2ICQUOK/VkEkMH09JGJu+O/EA0NL31hxlmF+wrwrSLaQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@svgdotjs/svg.draggable.js": "^3.0.4",
"@svgdotjs/svg.filter.js": "^3.0.8",
@@ -2954,9 +2972,9 @@
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3233,7 +3251,8 @@
"version": "1.11.13",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/debug": {
"version": "4.4.0",
@@ -3580,33 +3599,33 @@
}
},
"node_modules/eslint": {
"version": "9.23.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz",
"integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==",
"version": "9.39.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz",
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.19.2",
"@eslint/config-helpers": "^0.2.0",
"@eslint/core": "^0.12.0",
"@eslint/config-array": "^0.21.1",
"@eslint/config-helpers": "^0.4.2",
"@eslint/core": "^0.17.0",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "9.23.0",
"@eslint/plugin-kit": "^0.2.7",
"@eslint/js": "9.39.1",
"@eslint/plugin-kit": "^0.4.1",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2",
"@types/estree": "^1.0.6",
"@types/json-schema": "^7.0.15",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.6",
"debug": "^4.3.2",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^8.3.0",
"eslint-visitor-keys": "^4.2.0",
"espree": "^10.3.0",
"eslint-scope": "^8.4.0",
"eslint-visitor-keys": "^4.2.1",
"espree": "^10.4.0",
"esquery": "^1.5.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@@ -3730,6 +3749,7 @@
"integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.8",
@@ -3759,9 +3779,9 @@
}
},
"node_modules/eslint-plugin-import/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3867,9 +3887,9 @@
}
},
"node_modules/eslint-plugin-react/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3935,9 +3955,9 @@
}
},
"node_modules/eslint-scope": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
"integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
"integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -3952,9 +3972,9 @@
}
},
"node_modules/eslint-visitor-keys": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
"integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -3965,9 +3985,9 @@
}
},
"node_modules/eslint/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3989,15 +4009,15 @@
}
},
"node_modules/espree": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
"integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"acorn": "^8.14.0",
"acorn": "^8.15.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^4.2.0"
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4114,11 +4134,14 @@
}
},
"node_modules/fdir": {
"version": "6.4.3",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
"integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"picomatch": "^3 || ^4"
},
@@ -4993,9 +5016,9 @@
"license": "MIT"
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5125,6 +5148,12 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"license": "MIT"
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -5553,9 +5582,9 @@
"license": "ISC"
},
"node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5683,6 +5712,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -5705,6 +5735,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.26.0"
},
@@ -5713,21 +5744,19 @@
}
},
"node_modules/react-is": {
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz",
"integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==",
"version": "19.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz",
"integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==",
"license": "MIT"
},
"node_modules/react-router": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.4.1.tgz",
"integrity": "sha512-Vmizn9ZNzxfh3cumddqv3kLOKvc7AskUT0dC1prTabhiEi0U4A33LmkDOJ79tXaeSqCqMBXBU/ySX88W85+EUg==",
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.6.tgz",
"integrity": "sha512-Y1tUp8clYRXpfPITyuifmSoE2vncSME18uVLgaqyxh9H35JWpIfzHo+9y3Fzh5odk/jxPW29IgLgzcdwxGqyNA==",
"license": "MIT",
"dependencies": {
"@types/cookie": "^0.6.0",
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0",
"turbo-stream": "2.4.0"
"set-cookie-parser": "^2.6.0"
},
"engines": {
"node": ">=20.0.0"
@@ -5743,12 +5772,12 @@
}
},
"node_modules/react-router-dom": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.4.1.tgz",
"integrity": "sha512-L3/4tig0Lvs6m6THK0HRV4eHUdpx0dlJasgCxXKnavwhh4tKYgpuZk75HRYNoRKDyDWi9QgzGXsQ1oQSBlWpAA==",
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.6.tgz",
"integrity": "sha512-2MkC2XSXq6HjGcihnx1s0DBWQETI4mlis4Ux7YTLvP67xnGxCvq+BcCQSO81qQHVUTM1V53tl4iVVaY5sReCOA==",
"license": "MIT",
"dependencies": {
"react-router": "7.4.1"
"react-router": "7.9.6"
},
"engines": {
"node": ">=20.0.0"
@@ -6027,9 +6056,9 @@
}
},
"node_modules/set-cookie-parser": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
"license": "MIT"
},
"node_modules/set-function-length": {
@@ -6403,14 +6432,14 @@
"license": "MIT"
},
"node_modules/tinyglobby": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz",
"integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==",
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.4.3",
"picomatch": "^4.0.2"
"fdir": "^6.5.0",
"picomatch": "^4.0.3"
},
"engines": {
"node": ">=12.0.0"
@@ -6466,12 +6495,6 @@
"license": "0BSD",
"optional": true
},
"node_modules/turbo-stream": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz",
"integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
"license": "ISC"
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -6569,6 +6592,7 @@
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -6677,15 +6701,19 @@
}
},
"node_modules/vite": {
"version": "6.2.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz",
"integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==",
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.4.4",
"picomatch": "^4.0.2",
"postcss": "^8.5.3",
"rollup": "^4.30.1"
"rollup": "^4.34.9",
"tinyglobby": "^0.2.13"
},
"bin": {
"vite": "bin/vite.js"
@@ -6932,21 +6960,6 @@
"node": ">=0.10.0"
}
},
"node_modules/yaml": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz",
"integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==",
"dev": true,
"license": "ISC",
"optional": true,
"peer": true,
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",

View File

@@ -28,17 +28,18 @@
"dependencies": {
"@emotion/cache": "^11.14.0",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@fontsource-variable/dm-sans": "^5.2.5",
"@fontsource/barlow": "^5.2.5",
"@iconify/react": "^5.2.1",
"@mui/icons-material": "^7.2.0",
"@mui/icons-material": "^7.3.5",
"@mui/lab": "^7.0.0-beta.10",
"@mui/material": "^7.0.1",
"@mui/material": "^7.3.5",
"@mui/x-date-pickers": "^8.7.0",
"apexcharts": "^4.5.0",
"dayjs": "^1.11.13",
"es-toolkit": "^1.34.1",
"lodash.debounce": "^4.0.8",
"minimal-shared": "^1.0.7",
"react": "^19.1.0",
"react-apexcharts": "^1.7.0",
@@ -48,6 +49,7 @@
},
"devDependencies": {
"@eslint/js": "^9.23.0",
"@types/lodash.debounce": "^4.0.9",
"@types/node": "^22.14.0",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.1",

View File

@@ -0,0 +1,230 @@
[
{
"id": 1,
"name": "example1.pdf",
"addedWhen": "2024-01-12T10:00:00.000Z",
"addedWho": "TekH",
"attributes": [
{
"name": "invoiceNumber",
"serilizedValue": "INV-20250714-001"
},
{
"name": "customerName",
"serilizedValue": "John Doe"
},
{
"name": "startDate",
"serilizedValue": "2025-07-01"
},
{
"name": "endDate",
"serilizedValue": "2025-07-14"
},
{
"name": "minAmount",
"serilizedValue": "100.50"
},
{
"name": "maxAmount",
"serilizedValue": "1000.00"
},
{
"name": "taxIncluded",
"serilizedValue": "true"
},
{
"name": "createdAt",
"serilizedValue": "2025-07-10"
},
{
"name": "deliveryTime",
"serilizedValue": "15:30:00"
},
{
"name": "lastUpdated",
"serilizedValue": "2025-07-14T10:45:00"
}
]
},
{
"id": 2,
"name": "example2.pdf",
"addedWhen": "2024-02-03T09:30:00.000Z",
"addedWho": "bob",
"changedWhen": "2024-03-15T12:00:00.000Z",
"changedWho": "KammM",
"attributes": [
{
"name": "invoiceNumber",
"serilizedValue": "INV-20250701-007"
},
{
"name": "customerName",
"serilizedValue": "Jane Smith"
},
{
"name": "startDate",
"serilizedValue": "2025-06-01"
},
{
"name": "endDate",
"serilizedValue": "2025-06-30"
},
{
"name": "minAmount",
"serilizedValue": "250.00"
},
{
"name": "maxAmount",
"serilizedValue": "850.75"
},
{
"name": "taxIncluded",
"serilizedValue": "false"
},
{
"name": "createdAt",
"serilizedValue": "2025-06-15"
},
{
"name": "deliveryTime",
"serilizedValue": "09:00:00"
},
{
"name": "lastUpdated",
"serilizedValue": "2025-06-30T14:15:00"
}
]
},
{
"id": 3,
"name": "document1.docx",
"addedWhen": "2023-12-20T14:45:00.000Z",
"addedWho": "SchreiberM",
"attributes": [
{
"name": "invoiceNumber",
"serilizedValue": "INV-20250620-043"
},
{
"name": "customerName",
"serilizedValue": "Max Mustermann"
},
{
"name": "startDate",
"serilizedValue": "2025-05-01"
},
{
"name": "endDate",
"serilizedValue": "2025-05-15"
},
{
"name": "maxAmount",
"serilizedValue": "600.00"
},
{
"name": "taxIncluded",
"serilizedValue": "true"
},
{
"name": "createdAt",
"serilizedValue": "2025-05-02"
},
{
"name": "lastUpdated",
"serilizedValue": "2025-05-15T11:00:00"
}
]
},
{
"id": 4,
"name": "spreadsheet1.xlsx",
"addedWhen": "2024-05-01T08:15:00.000Z",
"addedWho": "KammM",
"changedWhen": "2024-06-10T16:20:00.000Z",
"changedWho": "OlgunR",
"attributes": [
{
"name": "invoiceNumber",
"serilizedValue": "INV-20250410-021"
},
{
"name": "startDate",
"serilizedValue": "2025-04-01"
},
{
"name": "endDate",
"serilizedValue": "2025-04-30"
},
{
"name": "minAmount",
"serilizedValue": "150.99"
},
{
"name": "maxAmount",
"serilizedValue": "999.99"
},
{
"name": "createdAt",
"serilizedValue": "2025-04-15"
},
{
"name": "deliveryTime",
"serilizedValue": "17:45:00"
},
{
"name": "lastUpdated",
"serilizedValue": "2025-04-30T18:30:00"
}
]
},
{
"id": 5,
"name": "report.docx",
"addedWhen": "2024-04-17T11:25:00.000Z",
"addedWho": "SchreiberM",
"attributes": [
{
"name": "invoiceNumber",
"serilizedValue": "INV-20250305-099"
},
{
"name": "customerName",
"serilizedValue": "Ali Veli"
},
{
"name": "startDate",
"serilizedValue": "2025-03-01"
},
{
"name": "endDate",
"serilizedValue": "2025-03-20"
},
{
"name": "minAmount",
"serilizedValue": "75.00"
},
{
"name": "maxAmount",
"serilizedValue": "500.00"
},
{
"name": "taxIncluded",
"serilizedValue": "false"
},
{
"name": "createdAt",
"serilizedValue": "2025-03-02"
},
{
"name": "deliveryTime",
"serilizedValue": "08:20:00"
},
{
"name": "lastUpdated",
"serilizedValue": "2025-03-20T09:30:00"
}
]
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -1,7 +1,7 @@
import { Doc } from 'src/api/document-service';
import { Product } from 'src/api/product-service';
import { Filter } from 'src/api/attribute-service';
import { Doc } from 'src/services/document-service';
import { Product } from 'src/services/product-service';
import { Attribute, Type } from 'src/services/attribute-service';
import {
_id,
@@ -114,12 +114,7 @@ export const _langs = [
value: 'de',
label: 'German',
icon: '/assets/icons/flags/ic-flag-de.svg',
},
{
value: 'fr',
label: 'French',
icon: '/assets/icons/flags/ic-flag-fr.svg',
},
}
];
// ----------------------------------------------------------------------
@@ -232,7 +227,7 @@ export const _products: Product[] = [
// ----------------------------------------------------------------------
export const _filters: Filter[] = [
export const _attributes: Attribute[] = [
{ id: 1, label: 'Rechnungsnummer', name: 'invoiceNumber', type: 'VARCHAR' },
{ id: 2, label: 'Kundenname', name: 'customerName', type: 'INTEGER' },
{ id: 3, label: 'Startdatum', name: 'startDate', type: 'DATE' },
@@ -249,6 +244,291 @@ export const _filters: Filter[] = [
// ----------------------------------------------------------------------
export const _documents: Doc[] = [
{
id: 1,
name: "example1.pdf",
addedWhen: new Date("2024-01-12T10:00:00Z"),
addedWho: "TekH",
attributes: [
{
name: "invoiceNumber",
serilizedValue: "INV-20250714-001",
type: 'VARCHAR'
},
{
name: "customerName",
serilizedValue: "John Doe",
type: 'VARCHAR'
},
{
name: "startDate",
serilizedValue: "2025-07-01",
type: 'DATE'
},
{
name: "endDate",
serilizedValue: "2025-07-14",
type: 'DATE'
},
{
name: "minAmount",
serilizedValue: "100.50",
type: 'DECIMAL'
},
{
name: "maxAmount",
serilizedValue: "1000.00",
type: 'DECIMAL'
},
{
name: "taxIncluded",
serilizedValue: "true",
type: 'BOOLEAN'
},
{
name: "createdAt",
serilizedValue: "2025-07-10",
type: 'DATE'
},
{
name: "deliveryTime",
serilizedValue: "15:30:00",
type: 'TIME'
},
{
name: "lastUpdated",
serilizedValue: "2025-07-14T10:45:00",
type: 'DATETIME'
}
]
},
{
id: 2,
name: "example2.pdf",
addedWhen: new Date("2024-02-03T09:30:00Z"),
addedWho: "bob",
changedWhen: new Date("2024-03-15T12:00:00Z"),
changedWho: "KammM",
attributes: [
{
name: "invoiceNumber",
serilizedValue: "INV-20250701-007",
type: 'VARCHAR'
},
{
name: "customerName",
serilizedValue: "Jane Smith",
type: 'VARCHAR'
},
{
name: "startDate",
serilizedValue: "2025-06-01",
type: 'DATE'
},
{
name: "endDate",
serilizedValue: "2025-06-30",
type: 'DATE'
},
{
name: "minAmount",
serilizedValue: "250.00",
type: 'DECIMAL'
},
{
name: "maxAmount",
serilizedValue: "850.75",
type: 'DECIMAL'
},
{
name: "taxIncluded",
serilizedValue: "false",
type: 'BOOLEAN'
},
{
name: "createdAt",
serilizedValue: "2025-06-15",
type: 'DATE'
},
{
name: "deliveryTime",
serilizedValue: "09:00:00",
type: 'TIME'
},
{
name: "lastUpdated",
serilizedValue: "2025-06-30T14:15:00",
type: 'DATETIME'
}
]
},
{
id: 3,
name: "document1.docx",
addedWhen: new Date("2023-12-20T14:45:00Z"),
addedWho: "SchreiberM",
attributes: [
{
name: "invoiceNumber",
serilizedValue: "INV-20250620-043",
type: 'VARCHAR'
},
{
name: "customerName",
serilizedValue: "Max Mustermann",
type: 'VARCHAR'
},
{
name: "startDate",
serilizedValue: "2025-05-01",
type: 'DATE'
},
{
name: "endDate",
serilizedValue: "2025-05-15",
type: 'DATE'
},
{
name: "maxAmount",
serilizedValue: "600.00",
type: 'DECIMAL'
},
{
name: "taxIncluded",
serilizedValue: "true",
type: 'BOOLEAN'
},
{
name: "createdAt",
serilizedValue: "2025-05-02",
type: 'DATE'
},
{
name: "lastUpdated",
serilizedValue: "2025-05-15T11:00:00",
type: 'DATETIME'
}
]
},
{
id: 4,
name: "spreadsheet1.xlsx",
addedWhen: new Date("2024-05-01T08:15:00Z"),
addedWho: "KammM",
changedWhen: new Date("2024-06-10T16:20:00Z"),
changedWho: "OlgunR",
attributes: [
{
name: "invoiceNumber",
serilizedValue: "INV-20250410-021",
type: 'VARCHAR'
},
{
name: "startDate",
serilizedValue: "2025-04-01",
type: 'DATE'
},
{
name: "endDate",
serilizedValue: "2025-04-30",
type: 'DATE'
},
{
name: "minAmount",
serilizedValue: "150.99",
type: 'DECIMAL'
},
{
name: "maxAmount",
serilizedValue: "999.99",
type: 'DECIMAL'
},
{
name: "createdAt",
serilizedValue: "2025-04-15",
type: 'DATE'
},
{
name: "deliveryTime",
serilizedValue: "17:45:00",
type: 'TIME'
},
{
name: "lastUpdated",
serilizedValue: "2025-04-30T18:30:00",
type: 'DATETIME'
}
]
},
{
id: 5,
name: "report.docx",
addedWhen: new Date("2024-04-17T11:25:00Z"),
addedWho: "SchreiberM",
attributes: [
{
name: "invoiceNumber",
serilizedValue: "INV-20250305-099",
type: 'VARCHAR'
},
{
name: "customerName",
serilizedValue: "Ali Veli",
type: 'VARCHAR'
},
{
name: "startDate",
serilizedValue: "2025-03-01",
type: 'DATE'
},
{
name: "endDate",
serilizedValue: "2025-03-20",
type: 'DATE'
},
{
name: "minAmount",
serilizedValue: "75.00",
type: 'DECIMAL'
},
{
name: "maxAmount",
serilizedValue: "500.00",
type: 'DECIMAL'
},
{
name: "taxIncluded",
serilizedValue: "false",
type: 'BOOLEAN'
},
{
name: "createdAt",
serilizedValue: "2025-03-02",
type: 'DATE'
},
{
name: "deliveryTime",
serilizedValue: "08:20:00",
type: 'TIME'
},
{
name: "lastUpdated",
serilizedValue: "2025-03-20T09:30:00",
type: 'DATETIME'
}
]
}
]
.map(doc => ({
...doc,
attributes: doc.attributes?.map(attr => ({
...attr,
type: attr.type as Type
}))
}))
.map(doc => Doc.map(doc));
function base64ToUint8Array(base64: string): Uint8Array {
const binaryString = atob(base64); // Decode base64 to binary string
const len = binaryString.length;
@@ -261,44 +541,19 @@ function base64ToUint8Array(base64: string): Uint8Array {
return bytes;
}
export const _documents: Doc[] = [
{
id: 1,
name: "example1.pdf",
data: base64ToUint8Array(_base64.example1_pdf),
addedWhen: new Date("2024-01-12T10:00:00Z"),
addedWho: "TekH"
},
{
id: 2,
name: "example2.pdf",
data: base64ToUint8Array(_base64.example2_pdf),
addedWhen: new Date("2024-02-03T09:30:00Z"),
addedWho: "bob",
changedWhen: new Date("2024-03-15T12:00:00Z"),
changedWho: "KammM"
},
{
id: 3,
name: "document1.docx",
data: base64ToUint8Array(_base64.document1_docx),
addedWhen: new Date("2023-12-20T14:45:00Z"),
addedWho: "SchreiberM"
},
{
id: 4,
name: "spreadsheet1.xlsx",
data: base64ToUint8Array(_base64.spreadsheet1_xlsx),
addedWhen: new Date("2024-05-01T08:15:00Z"),
addedWho: "KammM",
changedWhen: new Date("2024-06-10T16:20:00Z"),
changedWho: "OlgunR"
},
{
id: 5,
name: "report.docx",
data: base64ToUint8Array(_base64.report_docx),
addedWhen: new Date("2024-04-17T11:25:00Z"),
addedWho: "SchreiberM"
export function _genFile(name: string): Uint8Array | undefined {
switch (name) {
case "example1.pdf":
return base64ToUint8Array(_base64.example1_pdf);
case "example2.pdf":
return base64ToUint8Array(_base64.example2_pdf);
case "document1.docx":
return base64ToUint8Array(_base64.document1_docx);
case "spreadsheet1.xlsx":
return base64ToUint8Array(_base64.spreadsheet1_xlsx);
case "report.docx":
return base64ToUint8Array(_base64.report_docx);
default:
return undefined;
}
].map(doc => Doc.map(doc));
}

View File

@@ -1,66 +0,0 @@
import { _documents } from "src/_mock"
export class Doc {
static map(source?: Partial<Doc>): Doc {
const doc = new Doc();
Object.assign(doc, source);
return doc;
}
id!: number;
name!: string;
data!: Uint8Array;
addedWhen!: Date;
addedWho!: string;
changedWhen?: Date;
changedWho?: string;
getChangedInfo(separator: string = " | "): string | null {
const who = this.changedWho?.trim();
const when = this.changedWhen?.toLocaleDateString('de-DE');
if (!who && !when) {
return null;
}
return [who, when].filter(Boolean).join(separator);
}
get extension(): string | undefined {
const parts = this.name.split('.');
if (parts.length > 1 && parts[parts.length - 1].trim() !== '') {
return parts[parts.length - 1].toLowerCase();
}
return undefined;
}
get iconSrc(): string {
return `assets/icons/file/${this.extension ?? 'unknown'}.svg`;
}
}
export type DocQuery = {
id?: number | undefined,
name?: string | undefined
}
export function getDocuments(query: DocQuery | undefined = undefined): Promise<Doc[]> {
let documents = _documents;
if (query?.id)
documents = documents.filter(d => d.id === query.id);
if (query?.name)
documents = documents.filter(d => d.name === query.name);
return Promise.resolve(documents);
}
export function getDocumentById(id: number): Promise<Doc[]> {
return getDocuments({ id: id });
}
export function getDocumentByName(name: string): Promise<Doc[]> {
return getDocuments({ name: name });
}

View File

@@ -1,8 +1,9 @@
import 'src/global.css';
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import Fab from '@mui/material/Fab';
import KeyboardArrowUpRoundedIcon from '@mui/icons-material/KeyboardArrowUpRounded';
import { usePathname } from 'src/routes/hooks';
@@ -17,12 +18,28 @@ type AppProps = {
export default function App({ children }: AppProps) {
useScrollToTop();
const [showScrollTop, setShowScrollTop] = useState(false);
useEffect(() => {
const handleScroll = () => {
setShowScrollTop(window.scrollY > 160);
};
handleScroll();
window.addEventListener('scroll', handleScroll, { passive: true });
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const handleScrollTop = () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
};
const ddButton = () => (
<Fab
size="medium"
aria-label="Digital Data"
href="https://digitaldata.works/"
target="_blank"
aria-label="Scroll to top"
onClick={handleScrollTop}
sx={{
zIndex: 9,
right: 20,
@@ -30,14 +47,20 @@ export default function App({ children }: AppProps) {
width: 48,
height: 48,
position: 'fixed',
bgcolor: 'transparent',
boxShadow: 'none'
color: 'common.white',
bgcolor: '#a52431',
boxShadow: (theme) => theme.shadows[6],
opacity: showScrollTop ? 1 : 0,
pointerEvents: showScrollTop ? 'auto' : 'none',
transform: showScrollTop ? 'translateY(0)' : 'translateY(12px)',
transition: 'opacity 0.24s ease, transform 0.24s ease',
'&:hover': {
bgcolor: '#8c1e2a',
boxShadow: (theme) => theme.shadows[8],
},
}}
>
<img
src="/assets/images/dd-button-icon.webp"
alt="Digital Data"
/>
<KeyboardArrowUpRoundedIcon fontSize="medium" />
</Fab>
);

View File

@@ -0,0 +1,17 @@
type JsonViewerProps = {
data: any;
};
export function JsonViewer({ data }: JsonViewerProps) {
return (
<pre style={{
backgroundColor: '#f4f4f4',
padding: '1rem',
borderRadius: '5px',
width: '100%',
height: '100%'
}}>
{JSON.stringify(data)}
</pre>
);
}

View File

@@ -44,5 +44,5 @@ const ChartRoot = styled('div')(({ theme }) => ({
width: '100%',
flexShrink: 0,
position: 'relative',
borderRadius: theme.shape.borderRadius * 1.5,
borderRadius: theme.shape.borderRadius as any * 1.5,
}));

View File

@@ -100,7 +100,7 @@ export const LabelRoot = styled('span', {
padding: theme.spacing(0, 0.75),
fontSize: theme.typography.pxToRem(12),
fontWeight: theme.typography.fontWeightBold,
borderRadius: theme.shape.borderRadius * 0.75,
borderRadius: theme.shape.borderRadius as any * 0.75,
transition: theme.transitions.create(['all'], { duration: theme.transitions.duration.shorter }),
...defaultStyles,
...colorStyles,

View File

@@ -5,10 +5,11 @@ import type { Theme } from '@mui/material/styles';
export function dashboardLayoutVars(theme: Theme) {
return {
'--layout-transition-easing': 'linear',
'--layout-transition-duration': '120ms',
'--layout-transition-duration': '100ms',
'--layout-nav-vertical-width': '300px',
'--layout-dashboard-content-pt': theme.spacing(1),
'--layout-dashboard-content-pb': theme.spacing(8),
'--layout-dashboard-content-px': theme.spacing(5),
'--layout-header-zIndex': theme.zIndex.drawer + 2,
};
}

View File

@@ -6,6 +6,8 @@ import { useBoolean } from 'minimal-shared/hooks';
import Box from '@mui/material/Box';
import Alert from '@mui/material/Alert';
import { useTheme } from '@mui/material/styles';
import Typography from '@mui/material/Typography';
import useMediaQuery from '@mui/material/useMediaQuery';
import { _langs, _notifications } from 'src/_mock';
@@ -48,8 +50,19 @@ export function DashboardLayout({
layoutQuery = 'lg',
}: DashboardLayoutProps) {
const theme = useTheme();
const isDesktop = useMediaQuery(theme.breakpoints.up(layoutQuery));
const { value: open, onFalse: onClose, onTrue: onOpen } = useBoolean();
const {
value: mobileOpen,
onFalse: onMobileClose,
onToggle: onMobileToggle,
} = useBoolean();
const {
value: desktopOpen,
onFalse: onDesktopClose,
onToggle: onDesktopToggle,
} = useBoolean(true);
const renderHeader = () => {
const headerSlotProps: HeaderSectionProps['slotProps'] = {
@@ -58,6 +71,35 @@ export function DashboardLayout({
},
};
const inheritedHeaderSx = slotProps?.header?.sx;
const headerSx: HeaderSectionProps['sx'] = [
(t) => ({
bgcolor: '#a52431',
color: t.vars.palette.common.white,
zIndex: 'var(--layout-header-zIndex)',
'--color': t.vars.palette.common.white,
'& .MuiButtonBase-root, & .MuiIconButton-root, & .MuiTypography-root, & .MuiSvgIcon-root': {
color: t.vars.palette.common.white,
},
'& .MuiInputBase-root': {
color: t.vars.palette.common.white,
bgcolor: 'rgba(255, 255, 255, 0.12)',
'& .MuiInputBase-input::placeholder': {
color: 'rgba(255, 255, 255, 0.72)',
},
'& .MuiSvgIcon-root': {
color: t.vars.palette.common.white,
},
},
}),
...(Array.isArray(inheritedHeaderSx)
? inheritedHeaderSx
: inheritedHeaderSx
? [inheritedHeaderSx]
: []),
];
const headerSlots: HeaderSectionProps['slots'] = {
topArea: (
<Alert severity="info" sx={{ display: 'none', borderRadius: 0 }}>
@@ -65,14 +107,23 @@ export function DashboardLayout({
</Alert>
),
leftArea: (
<>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.25 }}>
{/** @slot Nav mobile */}
<MenuButton
onClick={onOpen}
sx={{ mr: 1, ml: -1, [theme.breakpoints.up(layoutQuery)]: { display: 'none' } }}
onClick={isDesktop ? onDesktopToggle : onMobileToggle}
sx={{ ml: -1 }}
/>
<NavMobile data={navData} open={open} onClose={onClose} workspaces={_workspaces} />
</>
<Typography variant="h6" sx={{ fontWeight: 700 }}>
Digital Data Hub
</Typography>
<NavMobile
data={navData}
open={mobileOpen}
onClose={onMobileClose}
workspaces={_workspaces}
layoutQuery={layoutQuery}
/>
</Box>
),
rightArea: (
<Box sx={{ display: 'flex', alignItems: 'center', gap: { xs: 0, sm: 0.75 } }}>
@@ -94,11 +145,12 @@ export function DashboardLayout({
return (
<HeaderSection
disableElevation
disableOffset
layoutQuery={layoutQuery}
{...slotProps?.header}
slots={{ ...headerSlots, ...slotProps?.header?.slots }}
slotProps={merge(headerSlotProps, slotProps?.header?.slotProps ?? {})}
sx={slotProps?.header?.sx}
sx={headerSx}
/>
);
};
@@ -117,7 +169,12 @@ export function DashboardLayout({
* @Sidebar
*************************************** */
sidebarSection={
<NavDesktop data={navData} layoutQuery={layoutQuery} workspaces={_workspaces} />
<NavDesktop
open={desktopOpen}
data={navData}
layoutQuery={layoutQuery}
workspaces={_workspaces}
/>
}
/** **************************************
* @Footer
@@ -129,9 +186,9 @@ export function DashboardLayout({
cssVars={{ ...dashboardLayoutVars(theme), ...cssVars }}
sx={[
{
[`& .${layoutClasses.sidebarContainer}`]: {
[`& .${layoutClasses.main}`]: {
[theme.breakpoints.up(layoutQuery)]: {
pl: 'var(--layout-nav-vertical-width)',
pl: desktopOpen ? 'var(--layout-nav-vertical-width)' : 0,
transition: theme.transitions.create(['padding-left'], {
easing: 'var(--layout-transition-easing)',
duration: 'var(--layout-transition-duration)',

View File

@@ -39,7 +39,8 @@ export function NavDesktop({
slots,
workspaces,
layoutQuery,
}: NavContentProps & { layoutQuery: Breakpoint }) {
open = true,
}: NavContentProps & { layoutQuery: Breakpoint; open?: boolean }) {
const theme = useTheme();
return (
@@ -47,15 +48,23 @@ export function NavDesktop({
sx={{
pt: 2.5,
px: 2.5,
top: 0,
top: 'var(--layout-header-desktop-height)',
left: 0,
height: 1,
height: 'calc(100% - var(--layout-header-desktop-height))',
display: 'none',
position: 'fixed',
flexDirection: 'column',
zIndex: 'var(--layout-nav-zIndex)',
width: 'var(--layout-nav-vertical-width)',
borderRight: `1px solid ${varAlpha(theme.vars.palette.grey['500Channel'], 0.12)}`,
bgcolor: '#ffffff',
color: '#5a1a22',
borderRight: `1px solid ${varAlpha('90 24 34', 0.08)}`,
transform: open ? 'translateX(0)' : 'translateX(-100%)',
transition: theme.transitions.create(['transform'], {
easing: 'var(--layout-transition-easing)',
duration: 'var(--layout-transition-duration)',
}),
pointerEvents: open ? 'auto' : 'none',
[theme.breakpoints.up(layoutQuery)]: {
display: 'flex',
},
@@ -76,8 +85,10 @@ export function NavMobile({
slots,
onClose,
workspaces,
}: NavContentProps & { open: boolean; onClose: () => void }) {
layoutQuery,
}: NavContentProps & { open: boolean; onClose: () => void; layoutQuery: Breakpoint }) {
const pathname = usePathname();
const theme = useTheme();
useEffect(() => {
if (open) {
@@ -94,8 +105,16 @@ export function NavMobile({
[`& .${drawerClasses.paper}`]: {
pt: 2.5,
px: 2.5,
top: 'var(--layout-header-mobile-height)',
overflow: 'unset',
height: 'calc(100% - var(--layout-header-mobile-height))',
width: 'var(--layout-nav-mobile-width)',
bgcolor: '#ffffff',
color: '#5a1a22',
[theme.breakpoints.up(layoutQuery)]: {
top: 'var(--layout-header-desktop-height)',
height: 'calc(100% - var(--layout-header-desktop-height))',
},
...sx,
},
}}
@@ -112,12 +131,8 @@ export function NavContent({ data, slots, workspaces, sx }: NavContentProps) {
return (
<>
<Logo />
{slots?.topArea}
<WorkspacesPopover data={workspaces} sx={{ my: 2 }} />
<Scrollbar fillContent>
<Box
component="nav"
@@ -156,14 +171,14 @@ export function NavContent({ data, slots, workspaces, sx }: NavContentProps) {
borderRadius: 0.75,
typography: 'body2',
fontWeight: 'fontWeightMedium',
color: theme.vars.palette.text.secondary,
color: '#5a1a22',
minHeight: 44,
...(isActived && {
fontWeight: 'fontWeightSemiBold',
color: theme.vars.palette.primary.main,
bgcolor: varAlpha(theme.vars.palette.primary.mainChannel, 0.08),
color: '#5a1a22',
bgcolor: 'rgba(90, 24, 34, 0.08)',
'&:hover': {
bgcolor: varAlpha(theme.vars.palette.primary.mainChannel, 0.16),
bgcolor: 'rgba(90, 24, 34, 0.14)',
},
}),
}),
@@ -188,7 +203,7 @@ export function NavContent({ data, slots, workspaces, sx }: NavContentProps) {
{slots?.bottomArea}
<NavUpgrade />
{/* <NavUpgrade /> */}
</>
);
}

View File

@@ -1,8 +1,10 @@
import { Label } from 'src/components/label';
import { SvgColor } from 'src/components/svg-color';
// ----------------------------------------------------------------------
// Navbar Icons
const icon = (name: string) => <SvgColor src={`/assets/icons/navbar/${name}.svg`} />;
const iconDD = (name: string) => <img src={`/assets/icons/dd-icons/${name}.ico`} alt="" style={{ width: 24, height: 24 }} />;
export type NavItem = {
title: string;
@@ -13,47 +15,48 @@ export type NavItem = {
export const navData = [
{
title: 'Product',
path: '/products',
icon: icon('ic-cart'),
//#region example component
// info: (
// <Label color="error" variant="inverted">
// +3
// </Label>
// ),
//#endregion
title: 'Dashboard',
path: '/',
icon: icon('ic-analytics'),
},
{
title: 'Document Search',
title: 'EasyFlow',
path: '/doc-search',
icon: icon('ic-doc-search'),
}
//#region example pages
// {
// title: 'Dashboard',
// path: '/',
// icon: icon('ic-analytics'),
// },
// {
// title: 'User',
// path: '/user',
// icon: icon('ic-user'),
// },
// {
// title: 'Blog',
// path: '/blog',
// icon: icon('ic-blog'),
// },
// {
// title: 'Sign in',
// path: '/sign-in',
// icon: icon('ic-lock'),
// },
// {
// title: 'Not found',
// path: '/404',
// icon: icon('ic-disabled'),
// },
//#endregion
icon: iconDD('DD_easyFLOW_ICON'),
},
{
title: 'TaskFlow',
path: '/blog',
icon: iconDD('DD_taskFLOW_ICON'),
info: (
<Label color="error" variant="inverted">
+3
</Label>
)
},
{
title: 'OrgFlow',
path: '/products',
icon: iconDD('DD_orgFLOW_ICON'),
},
{
title: 'SignFlow',
path: '/user',
icon: iconDD('DD_signFLOW_ICON'),
},
{
title: 'ChartFlow',
path: '/chart-flow',
icon: icon('ic-analytics'),
},
{
title: 'Sign in',
path: '/sign-in',
icon: icon('ic-lock'),
},
{
title: 'Not found',
path: '/404',
icon: icon('ic-disabled'),
},
];

View File

@@ -0,0 +1,20 @@
import { CONFIG } from 'src/config-global';
import { ChartsView } from 'src/sections/charts/view';
// ----------------------------------------------------------------------
export default function Page() {
return (
<>
<title>{`Dashboard - ${CONFIG.appName}`}</title>
<meta
name="description"
content="The starting point for your next project with Minimal UI Kit, built on the newest version of Material-UI ©, ready to be customized to your style"
/>
<meta name="keywords" content="react,material,kit,application,dashboard,admin,template" />
< ChartsView/>
</>
);
}

View File

@@ -1,6 +1,6 @@
import { CONFIG } from 'src/config-global';
import { OverviewAnalyticsView as DashboardView } from 'src/sections/overview/view';
import { OverviewAnalyticsView } from 'src/sections/overview/view';
// ----------------------------------------------------------------------
@@ -14,7 +14,7 @@ export default function Page() {
/>
<meta name="keywords" content="react,material,kit,application,dashboard,admin,template" />
<DashboardView />
<OverviewAnalyticsView />
</>
);
}

View File

@@ -1,27 +1,15 @@
import { useEffect, useState } from 'react';
import { _posts } from 'src/_mock';
import { CONFIG } from 'src/config-global';
import { Doc, getDocuments } from 'src/api/document-service';
import { DocSearchView } from 'src/sections/document/view';
// ----------------------------------------------------------------------
export default function Page() {
const [docs, setDocs] = useState<Doc[]>([]);
useEffect(() => {
getDocuments({}).then((res) => {
setDocs(res);
});
}, []);
return (
<>
<title>{`Document Search - ${CONFIG.appName}`}</title>
<DocSearchView docs={docs} />
<DocSearchView />
</>
);
}

View File

@@ -19,6 +19,7 @@ export const SignInPage = lazy(() => import('src/pages/sign-in'));
export const ProductsPage = lazy(() => import('src/pages/products'));
export const Page404 = lazy(() => import('src/pages/page-not-found'));
export const DocumentSearch = lazy(() => import('src/pages/doc-search'));
export const ChartFlowPage = lazy(() => import('src/pages/charts'));
const renderFallback = () => (
<Box
@@ -50,11 +51,12 @@ export const routesSection: RouteObject[] = [
</DashboardLayout>
),
children: [
{ index: true, element: <ProductsPage /> },
{ index: true, element: <DashboardPage /> },
{ path: 'doc-search', element: <DocumentSearch /> },
{ path: 'products', element: <ProductsPage /> },
{ path: 'user', element: <UserPage /> },
{ path: 'blog', element: <BlogPage /> },
{ path: 'chart-flow', element: <ChartFlowPage /> },
],
},
{

View File

@@ -0,0 +1,82 @@
import type { CardProps } from '@mui/material/Card';
import type { ChartOptions } from 'src/components/chart';
import Card from '@mui/material/Card';
import CardHeader from '@mui/material/CardHeader';
import { useTheme, alpha as hexAlpha } from '@mui/material/styles';
import { fNumber } from 'src/utils/format-number';
import { Chart, useChart } from 'src/components/chart';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
chart: {
colors?: string[];
categories?: string[];
series: {
name: string;
data: number[];
}[];
options?: ChartOptions;
};
};
export function AnalyticsConversionRates({ title, subheader, chart, sx, ...other }: Props) {
const theme = useTheme();
const chartColors = chart.colors ?? [
theme.palette.primary.dark,
hexAlpha(theme.palette.primary.dark, 0.24),
];
const chartOptions = useChart({
colors: chartColors,
stroke: { width: 2, colors: ['transparent'] },
tooltip: {
shared: true,
intersect: false,
y: {
formatter: (value: number) => fNumber(value),
title: { formatter: (seriesName: string) => `${seriesName}: ` },
},
},
xaxis: { categories: chart.categories },
dataLabels: {
enabled: true,
offsetX: -6,
style: { fontSize: '10px', colors: ['#FFFFFF', theme.palette.text.primary] },
},
plotOptions: {
bar: {
horizontal: true,
borderRadius: 2,
barHeight: '48%',
dataLabels: { position: 'top' },
},
},
...chart.options,
});
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Chart
type="bar"
series={chart.series}
options={chartOptions}
slotProps={{ loading: { p: 2.5 } }}
sx={{
pl: 1,
py: 2.5,
pr: 2.5,
height: 360,
}}
/>
</Card>
);
}

View File

@@ -0,0 +1,73 @@
import type { CardProps } from '@mui/material/Card';
import type { ChartOptions } from 'src/components/chart';
import Card from '@mui/material/Card';
import Divider from '@mui/material/Divider';
import { useTheme } from '@mui/material/styles';
import CardHeader from '@mui/material/CardHeader';
import { Chart, useChart, ChartLegends } from 'src/components/chart';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
chart: {
colors?: string[];
categories: string[];
series: {
name: string;
data: number[];
}[];
options?: ChartOptions;
};
};
export function AnalyticsCurrentSubject({ title, subheader, chart, sx, ...other }: Props) {
const theme = useTheme();
const chartColors = chart.colors ?? [
theme.palette.primary.main,
theme.palette.warning.main,
theme.palette.info.main,
];
const chartOptions = useChart({
colors: chartColors,
stroke: { width: 2 },
fill: { opacity: 0.48 },
xaxis: {
categories: chart.categories,
labels: { style: { colors: Array.from({ length: 6 }, () => theme.palette.text.secondary) } },
},
...chart.options,
});
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Chart
type="radar"
series={chart.series}
options={chartOptions}
slotProps={{ loading: { py: 2.5 } }}
sx={{
my: 1,
mx: 'auto',
width: 300,
height: 300,
}}
/>
<Divider sx={{ borderStyle: 'dashed' }} />
<ChartLegends
labels={chart.series.map((item) => item.name)}
colors={chartOptions?.colors}
sx={{ p: 3, justifyContent: 'center' }}
/>
</Card>
);
}

View File

@@ -0,0 +1,81 @@
import type { CardProps } from '@mui/material/Card';
import type { ChartOptions } from 'src/components/chart';
import Card from '@mui/material/Card';
import Divider from '@mui/material/Divider';
import { useTheme } from '@mui/material/styles';
import CardHeader from '@mui/material/CardHeader';
import { fNumber } from 'src/utils/format-number';
import { Chart, useChart, ChartLegends } from 'src/components/chart';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
chart: {
colors?: string[];
series: {
label: string;
value: number;
}[];
options?: ChartOptions;
};
};
export function AnalyticsCurrentVisits({ title, subheader, chart, sx, ...other }: Props) {
const theme = useTheme();
const chartSeries = chart.series.map((item) => item.value);
const chartColors = chart.colors ?? [
theme.palette.primary.main,
theme.palette.warning.light,
theme.palette.info.dark,
theme.palette.error.main,
];
const chartOptions = useChart({
chart: { sparkline: { enabled: true } },
colors: chartColors,
labels: chart.series.map((item) => item.label),
stroke: { width: 0 },
dataLabels: { enabled: true, dropShadow: { enabled: false } },
tooltip: {
y: {
formatter: (value: number) => fNumber(value),
title: { formatter: (seriesName: string) => `${seriesName}` },
},
},
plotOptions: { pie: { donut: { labels: { show: false } } } },
...chart.options,
});
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Chart
type="pie"
series={chartSeries}
options={chartOptions}
sx={{
my: 6,
mx: 'auto',
width: { xs: 240, xl: 260 },
height: { xs: 240, xl: 260 },
}}
/>
<Divider sx={{ borderStyle: 'dashed' }} />
<ChartLegends
labels={chartOptions?.labels}
colors={chartOptions?.colors}
sx={{ p: 3, justifyContent: 'center' }}
/>
</Card>
);
}

View File

@@ -0,0 +1,103 @@
import type { BoxProps } from '@mui/material/Box';
import type { CardProps } from '@mui/material/Card';
import Box from '@mui/material/Box';
import Link from '@mui/material/Link';
import Card from '@mui/material/Card';
import Button from '@mui/material/Button';
import Avatar from '@mui/material/Avatar';
import CardHeader from '@mui/material/CardHeader';
import ListItemText from '@mui/material/ListItemText';
import { fToNow } from 'src/utils/format-time';
import { Iconify } from 'src/components/iconify';
import { Scrollbar } from 'src/components/scrollbar';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
list: {
id: string;
title: string;
coverUrl: string;
description: string;
postedAt: string | number | null;
}[];
};
export function AnalyticsNews({ title, subheader, list, sx, ...other }: Props) {
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} sx={{ mb: 1 }} />
<Scrollbar sx={{ minHeight: 405 }}>
<Box sx={{ minWidth: 640 }}>
{list.map((item) => (
<Item key={item.id} item={item} />
))}
</Box>
</Scrollbar>
<Box sx={{ p: 2, textAlign: 'right' }}>
<Button
size="small"
color="inherit"
endIcon={<Iconify icon="eva:arrow-ios-forward-fill" width={18} sx={{ ml: -0.5 }} />}
>
View all
</Button>
</Box>
</Card>
);
}
// ----------------------------------------------------------------------
type ItemProps = BoxProps & {
item: Props['list'][number];
};
function Item({ item, sx, ...other }: ItemProps) {
return (
<Box
sx={[
(theme) => ({
py: 2,
px: 3,
gap: 2,
display: 'flex',
alignItems: 'center',
borderBottom: `dashed 1px ${theme.vars.palette.divider}`,
}),
...(Array.isArray(sx) ? sx : [sx]),
]}
{...other}
>
<Avatar
variant="rounded"
alt={item.title}
src={item.coverUrl}
sx={{ width: 48, height: 48, flexShrink: 0 }}
/>
<ListItemText
primary={<Link color="inherit">{item.title}</Link>}
secondary={item.description}
slotProps={{
primary: { noWrap: true },
secondary: {
noWrap: true,
sx: { mt: 0.5 },
},
}}
/>
<Box sx={{ flexShrink: 0, typography: 'caption', color: 'text.disabled' }}>
{fToNow(item.postedAt)}
</Box>
</Box>
);
}

View File

@@ -0,0 +1,77 @@
import type { CardProps } from '@mui/material/Card';
import type { TimelineItemProps } from '@mui/lab/TimelineItem';
import Card from '@mui/material/Card';
import Timeline from '@mui/lab/Timeline';
import TimelineDot from '@mui/lab/TimelineDot';
import Typography from '@mui/material/Typography';
import CardHeader from '@mui/material/CardHeader';
import TimelineContent from '@mui/lab/TimelineContent';
import TimelineSeparator from '@mui/lab/TimelineSeparator';
import TimelineConnector from '@mui/lab/TimelineConnector';
import TimelineItem, { timelineItemClasses } from '@mui/lab/TimelineItem';
import { fDateTime } from 'src/utils/format-time';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
list: {
id: string;
type: string;
title: string;
time: string | number | null;
}[];
};
export function AnalyticsOrderTimeline({ title, subheader, list, sx, ...other }: Props) {
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Timeline
sx={{ m: 0, p: 3, [`& .${timelineItemClasses.root}:before`]: { flex: 0, padding: 0 } }}
>
{list.map((item, index) => (
<Item key={item.id} item={item} lastItem={index === list.length - 1} />
))}
</Timeline>
</Card>
);
}
// ----------------------------------------------------------------------
type ItemProps = TimelineItemProps & {
lastItem: boolean;
item: Props['list'][number];
};
function Item({ item, lastItem, ...other }: ItemProps) {
return (
<TimelineItem {...other}>
<TimelineSeparator>
<TimelineDot
color={
(item.type === 'order1' && 'primary') ||
(item.type === 'order2' && 'success') ||
(item.type === 'order3' && 'info') ||
(item.type === 'order4' && 'warning') ||
'error'
}
/>
{lastItem ? null : <TimelineConnector />}
</TimelineSeparator>
<TimelineContent>
<Typography variant="subtitle2">{item.title}</Typography>
<Typography variant="caption" sx={{ color: 'text.disabled' }}>
{fDateTime(item.time)}
</Typography>
</TimelineContent>
</TimelineItem>
);
}

View File

@@ -0,0 +1,179 @@
import type { BoxProps } from '@mui/material/Box';
import type { CardProps } from '@mui/material/Card';
import { useState } from 'react';
import { usePopover } from 'minimal-shared/hooks';
import Box from '@mui/material/Box';
import Card from '@mui/material/Card';
import Stack from '@mui/material/Stack';
import Popover from '@mui/material/Popover';
import Divider from '@mui/material/Divider';
import MenuList from '@mui/material/MenuList';
import Checkbox from '@mui/material/Checkbox';
import IconButton from '@mui/material/IconButton';
import CardHeader from '@mui/material/CardHeader';
import FormControlLabel from '@mui/material/FormControlLabel';
import MenuItem, { menuItemClasses } from '@mui/material/MenuItem';
import { Iconify } from 'src/components/iconify';
import { Scrollbar } from 'src/components/scrollbar';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
list: {
id: string;
name: string;
}[];
};
export function AnalyticsTasks({ title, subheader, list, sx, ...other }: Props) {
const [selected, setSelected] = useState(['2']);
const handleClickComplete = (taskId: string) => {
const tasksCompleted = selected.includes(taskId)
? selected.filter((value) => value !== taskId)
: [...selected, taskId];
setSelected(tasksCompleted);
};
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} sx={{ mb: 1 }} />
<Scrollbar sx={{ minHeight: 304 }}>
<Stack divider={<Divider sx={{ borderStyle: 'dashed' }} />} sx={{ minWidth: 560 }}>
{list.map((item) => (
<TaskItem
key={item.id}
item={item}
selected={selected.includes(item.id)}
onChange={() => handleClickComplete(item.id)}
/>
))}
</Stack>
</Scrollbar>
</Card>
);
}
// ----------------------------------------------------------------------
type TaskItemProps = BoxProps & {
selected: boolean;
item: Props['list'][number];
onChange: (id: string) => void;
};
function TaskItem({ item, selected, onChange, sx, ...other }: TaskItemProps) {
const menuActions = usePopover();
const handleMarkComplete = () => {
menuActions.onClose();
console.info('MARK COMPLETE', item.id);
};
const handleShare = () => {
menuActions.onClose();
console.info('SHARE', item.id);
};
const handleEdit = () => {
menuActions.onClose();
console.info('EDIT', item.id);
};
const handleDelete = () => {
menuActions.onClose();
console.info('DELETE', item.id);
};
return (
<>
<Box
sx={[
() => ({
pl: 2,
pr: 1,
py: 1.5,
display: 'flex',
...(selected && {
color: 'text.disabled',
textDecoration: 'line-through',
}),
}),
...(Array.isArray(sx) ? sx : [sx]),
]}
{...other}
>
<FormControlLabel
label={item.name}
control={
<Checkbox
disableRipple
checked={selected}
onChange={onChange}
slotProps={{ input: { id: `${item.name}-checkbox` } }}
/>
}
sx={{ flexGrow: 1, m: 0 }}
/>
<IconButton color={menuActions.open ? 'inherit' : 'default'} onClick={menuActions.onOpen}>
<Iconify icon="eva:more-vertical-fill" />
</IconButton>
</Box>
<Popover
open={menuActions.open}
anchorEl={menuActions.anchorEl}
onClose={menuActions.onClose}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
>
<MenuList
disablePadding
sx={{
p: 0.5,
gap: 0.5,
display: 'flex',
flexDirection: 'column',
[`& .${menuItemClasses.root}`]: {
pl: 1,
pr: 2,
gap: 2,
borderRadius: 0.75,
[`&.${menuItemClasses.selected}`]: { bgcolor: 'action.selected' },
},
}}
>
<MenuItem onClick={handleMarkComplete}>
<Iconify icon="solar:check-circle-bold" />
Mark complete
</MenuItem>
<MenuItem onClick={handleEdit}>
<Iconify icon="solar:pen-bold" />
Edit
</MenuItem>
<MenuItem onClick={handleShare}>
<Iconify icon="solar:share-bold" />
Share
</MenuItem>
<Divider sx={{ borderStyle: 'dashed' }} />
<MenuItem onClick={handleDelete} sx={{ color: 'error.main' }}>
<Iconify icon="solar:trash-bin-trash-bold" />
Delete
</MenuItem>
</MenuList>
</Popover>
</>
);
}

View File

@@ -0,0 +1,64 @@
import type { CardProps } from '@mui/material/Card';
import { varAlpha } from 'minimal-shared/utils';
import Box from '@mui/material/Box';
import Card from '@mui/material/Card';
import CardHeader from '@mui/material/CardHeader';
import Typography from '@mui/material/Typography';
import { fShortenNumber } from 'src/utils/format-number';
import { Iconify } from 'src/components/iconify';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
list: { value: string; label: string; total: number }[];
};
export function AnalyticsTrafficBySite({ title, subheader, list, sx, ...other }: Props) {
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Box
sx={{
p: 3,
gap: 2,
display: 'grid',
gridTemplateColumns: 'repeat(2, 1fr)',
}}
>
{list.map((site) => (
<Box
key={site.label}
sx={(theme) => ({
py: 2.5,
display: 'flex',
borderRadius: 1.5,
textAlign: 'center',
alignItems: 'center',
flexDirection: 'column',
border: `solid 1px ${varAlpha(theme.vars.palette.grey['500Channel'], 0.12)}`,
})}
>
{site.value === 'twitter' && <Iconify width={32} icon="socials:twitter" />}
{site.value === 'facebook' && <Iconify width={32} icon="socials:facebook" />}
{site.value === 'google' && <Iconify width={32} icon="socials:google" />}
{site.value === 'linkedin' && <Iconify width={32} icon="socials:linkedin" />}
<Typography variant="h6" sx={{ mt: 1 }}>
{fShortenNumber(site.total)}
</Typography>
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
{site.label}
</Typography>
</Box>
))}
</Box>
</Card>
);
}

View File

@@ -0,0 +1,61 @@
import type { CardProps } from '@mui/material/Card';
import type { ChartOptions } from 'src/components/chart';
import Card from '@mui/material/Card';
import CardHeader from '@mui/material/CardHeader';
import { useTheme, alpha as hexAlpha } from '@mui/material/styles';
import { Chart, useChart } from 'src/components/chart';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
chart: {
colors?: string[];
categories?: string[];
series: {
name: string;
data: number[];
}[];
options?: ChartOptions;
};
};
export function AnalyticsWebsiteVisits({ title, subheader, chart, sx, ...other }: Props) {
const theme = useTheme();
const chartColors = chart.colors ?? [
hexAlpha(theme.palette.primary.dark, 0.8),
hexAlpha(theme.palette.warning.main, 0.8),
];
const chartOptions = useChart({
colors: chartColors,
stroke: { width: 2, colors: ['transparent'] },
xaxis: { categories: chart.categories },
legend: { show: true },
tooltip: { y: { formatter: (value: number) => `${value} visits` } },
...chart.options,
});
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Chart
type="bar"
series={chart.series}
options={chartOptions}
slotProps={{ loading: { p: 2.5 } }}
sx={{
pl: 1,
py: 2.5,
pr: 2.5,
height: 364,
}}
/>
</Card>
);
}

View File

@@ -0,0 +1,163 @@
import type { CardProps } from '@mui/material/Card';
import type { PaletteColorKey } from 'src/theme/core';
import type { ChartOptions } from 'src/components/chart';
import { varAlpha } from 'minimal-shared/utils';
import Box from '@mui/material/Box';
import Card from '@mui/material/Card';
import { useTheme } from '@mui/material/styles';
import { fNumber, fPercent, fShortenNumber } from 'src/utils/format-number';
import { Iconify } from 'src/components/iconify';
import { SvgColor } from 'src/components/svg-color';
import { Chart, useChart } from 'src/components/chart';
// ----------------------------------------------------------------------
type Props = CardProps & {
title: string;
total: number;
percent: number;
color?: PaletteColorKey;
icon: React.ReactNode;
details?: { label: string; value: number }[];
loading?: boolean;
chart: {
series: number[];
categories: string[];
options?: ChartOptions;
};
};
export function AnalyticsWidgetSummary({
sx,
icon,
title,
total,
chart,
percent,
color = 'primary',
details,
loading = false,
...other
}: Props) {
const theme = useTheme();
const chartColors = [theme.palette[color].dark];
const chartOptions = useChart({
chart: { sparkline: { enabled: true } },
colors: chartColors,
xaxis: { categories: chart.categories },
grid: {
padding: {
top: 6,
left: 6,
right: 6,
bottom: 6,
},
},
tooltip: {
y: { formatter: (value: number) => fNumber(value), title: { formatter: () => '' } },
},
markers: {
strokeWidth: 0,
},
...chart.options,
});
const renderTrending = () => (
<Box
sx={{
top: 16,
gap: 0.5,
right: 16,
display: 'flex',
position: 'absolute',
alignItems: 'center',
}}
>
<Iconify width={20} icon={percent < 0 ? 'eva:trending-down-fill' : 'eva:trending-up-fill'} />
<Box component="span" sx={{ typography: 'subtitle2' }}>
{percent > 0 && '+'}
{fPercent(percent)}
</Box>
</Box>
);
return (
<Card
sx={[
() => ({
p: 3,
boxShadow: 'none',
position: 'relative',
color: `${color}.darker`,
backgroundColor: 'common.white',
backgroundImage: `linear-gradient(135deg, ${varAlpha(theme.vars.palette[color].lighterChannel, 0.48)}, ${varAlpha(theme.vars.palette[color].lightChannel, 0.48)})`,
}),
...(Array.isArray(sx) ? sx : [sx]),
]}
{...other}
>
<Box sx={{ width: 48, height: 48, mb: 3 }}>{icon}</Box>
{renderTrending()}
<Box
sx={{
display: 'flex',
flexWrap: 'wrap',
alignItems: 'flex-end',
justifyContent: 'flex-end',
}}
>
<Box sx={{ flexGrow: 1, minWidth: 112 }}>
<Box sx={{ mb: 1, typography: 'subtitle2' }}>{title}</Box>
<Box sx={{ typography: 'h4' }}>{fShortenNumber(total)}</Box>
{details?.length ? (
<Box component="ul" sx={{ mt: 1.5, mb: 0, pl: 0, listStyle: 'none', gap: 0.5, display: 'grid' }}>
{details.map((item) => (
<Box
component="li"
key={item.label}
sx={{ display: 'flex', justifyContent: 'space-between', typography: 'caption', color: 'text.secondary' }}
>
<Box component="span">{item.label}</Box>
<Box component="span" sx={{ color: 'text.primary', fontWeight: 'fontWeightSemiBold' }}>
{loading ? '…' : fShortenNumber(item.value)}
</Box>
</Box>
))}
</Box>
) : null}
</Box>
<Chart
type="line"
series={[{ data: chart.series }]}
options={chartOptions}
sx={{ width: 84, height: 56 }}
/>
</Box>
<SvgColor
src="/assets/background/shape-square.svg"
sx={{
top: 0,
left: -20,
width: 240,
zIndex: -1,
height: 240,
opacity: 0.24,
position: 'absolute',
color: `${color}.main`,
}}
/>
</Card>
);
}

View File

@@ -0,0 +1,156 @@
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import { DashboardContent } from 'src/layouts/dashboard';
import { _posts, _tasks, _traffic, _timeline } from 'src/_mock';
import { AnalyticsNews } from '../analytics-news';
import { AnalyticsTasks } from '../analytics-tasks';
import { AnalyticsCurrentVisits } from '../analytics-current-visits';
import { AnalyticsOrderTimeline } from '../analytics-order-timeline';
import { AnalyticsWebsiteVisits } from '../analytics-website-visits';
import { AnalyticsWidgetSummary } from '../analytics-widget-summary';
import { AnalyticsTrafficBySite } from '../analytics-traffic-by-site';
import { AnalyticsCurrentSubject } from '../analytics-current-subject';
import { AnalyticsConversionRates } from '../analytics-conversion-rates';
// ----------------------------------------------------------------------
export function ChartsView() {
return (
<DashboardContent maxWidth="xl">
<Typography variant="h4" sx={{ mb: { xs: 3, md: 5 } }}>
Hi, Welcome back 👋
</Typography>
<Grid container spacing={3}>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<AnalyticsWidgetSummary
title="Weekly sales"
percent={2.6}
total={714000}
icon={<img alt="Weekly sales" src="/assets/icons/glass/ic-glass-bag.svg" />}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [22, 8, 35, 50, 82, 84, 77, 12],
}}
/>
</Grid>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<AnalyticsWidgetSummary
title="New users"
percent={-0.1}
total={1352831}
color="secondary"
icon={<img alt="New users" src="/assets/icons/glass/ic-glass-users.svg" />}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [56, 47, 40, 62, 73, 30, 23, 54],
}}
/>
</Grid>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<AnalyticsWidgetSummary
title="Purchase orders"
percent={2.8}
total={1723315}
color="warning"
icon={<img alt="Purchase orders" src="/assets/icons/glass/ic-glass-buy.svg" />}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [40, 70, 50, 28, 70, 75, 7, 64],
}}
/>
</Grid>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<AnalyticsWidgetSummary
title="Messages"
percent={3.6}
total={234}
color="error"
icon={<img alt="Messages" src="/assets/icons/glass/ic-glass-message.svg" />}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [56, 30, 23, 54, 47, 40, 62, 73],
}}
/>
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 4 }}>
<AnalyticsCurrentVisits
title="Current visits"
chart={{
series: [
{ label: 'America', value: 3500 },
{ label: 'Asia', value: 2500 },
{ label: 'Europe', value: 1500 },
{ label: 'Africa', value: 500 },
],
}}
/>
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 8 }}>
<AnalyticsWebsiteVisits
title="Website visits"
subheader="(+43%) than last year"
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'],
series: [
{ name: 'Team A', data: [43, 33, 22, 37, 67, 68, 37, 24, 55] },
{ name: 'Team B', data: [51, 70, 47, 67, 40, 37, 24, 70, 24] },
],
}}
/>
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 8 }}>
<AnalyticsConversionRates
title="Conversion rates"
subheader="(+43%) than last year"
chart={{
categories: ['Italy', 'Japan', 'China', 'Canada', 'France'],
series: [
{ name: '2022', data: [44, 55, 41, 64, 22] },
{ name: '2023', data: [53, 32, 33, 52, 13] },
],
}}
/>
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 4 }}>
<AnalyticsCurrentSubject
title="Current subject"
chart={{
categories: ['English', 'History', 'Physics', 'Geography', 'Chinese', 'Math'],
series: [
{ name: 'Series 1', data: [80, 50, 30, 40, 100, 20] },
{ name: 'Series 2', data: [20, 30, 40, 80, 20, 80] },
{ name: 'Series 3', data: [44, 76, 78, 13, 43, 10] },
],
}}
/>
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 8 }}>
<AnalyticsNews title="News" list={_posts.slice(0, 5)} />
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 4 }}>
<AnalyticsOrderTimeline title="Order timeline" list={_timeline} />
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 4 }}>
<AnalyticsTrafficBySite title="Traffic by site" list={_traffic} />
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 8 }}>
<AnalyticsTasks title="Tasks" list={_tasks} />
</Grid>
</Grid>
</DashboardContent>
);
}

View File

@@ -0,0 +1 @@
export * from './charts-view';

View File

@@ -9,10 +9,12 @@ import Link from '@mui/material/Link';
import Card from '@mui/material/Card';
import Typography from '@mui/material/Typography';
import { Doc } from 'src/api/document-service';
import { Doc } from 'src/services/document-service';
import { Iconify } from 'src/components/iconify';
import { SvgColor } from 'src/components/svg-color';
import DocFullView from './view/doc-full-view';
// ----------------------------------------------------------------------
export function DocItem({
@@ -45,7 +47,7 @@ export function DocItem({
//#endregion
const [openViewDoc, setOpenViewDoc] = useState(false);
const renderTitle = (
<Link
color="inherit"
@@ -151,49 +153,61 @@ export function DocItem({
/>
);
return (
<Card sx={sx} {...other}>
<Box
sx={(theme) => ({
position: 'relative',
pt: 'calc(100% * 3 / 4)',
...((large || long) && {
pt: 'calc(100% * 4 / 3)',
'&:after': {
top: 0,
content: "''",
width: '100%',
height: '100%',
position: 'absolute',
bgcolor: varAlpha(theme.palette.grey['900Channel'], 0.72),
},
}),
...(large && {
pt: {
xs: 'calc(100% * 4 / 3)',
sm: 'calc(100% * 3 / 4.66)',
},
}),
})}
>
{renderShape}
{renderCover}
</Box>
sx ??= {
cursor: 'pointer',
transition: 'transform 0.3s ease, box-shadow 0.3s ease',
'&:hover': {
transform: 'scale(1.03)',
boxShadow: 6,
}
}
<Box
sx={(theme) => ({
p: theme.spacing(6, 3, 3, 3),
...((large || long) && {
width: 1,
bottom: 0,
position: 'absolute',
}),
})}
>
{renderDate}
{renderTitle}
{renderInfo}
</Box>
</Card>
return (
<>
<DocFullView data={doc.data} open={openViewDoc} handleClose={() => setOpenViewDoc(false)} format={doc.extension} />
<Card sx={sx} {...other} onClick={() => setOpenViewDoc(true)}>
<Box
sx={(theme) => ({
position: 'relative',
pt: 'calc(100% * 3 / 4)',
...((large || long) && {
pt: 'calc(100% * 4 / 3)',
'&:after': {
top: 0,
content: "''",
width: '100%',
height: '100%',
position: 'absolute',
bgcolor: varAlpha(theme.palette.grey['900Channel'], 0.72),
},
}),
...(large && {
pt: {
xs: 'calc(100% * 4 / 3)',
sm: 'calc(100% * 3 / 4.66)',
},
}),
})}
>
{renderShape}
{renderCover}
</Box>
<Box
sx={(theme) => ({
p: theme.spacing(6, 3, 3, 3),
...((large || long) && {
width: 1,
bottom: 0,
position: 'absolute',
}),
})}
>
{renderDate}
{renderTitle}
{renderInfo}
</Box>
</Card>
</>
);
}

View File

@@ -4,7 +4,7 @@ import TextField from '@mui/material/TextField';
import InputAdornment from '@mui/material/InputAdornment';
import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete';
import { Doc } from 'src/api/document-service';
import { Doc } from 'src/services/document-service';
import { Iconify } from 'src/components/iconify';

View File

@@ -1,27 +1,42 @@
import { useState } from 'react';
import debounce from 'lodash.debounce';
import { useState, useMemo } from 'react';
import TextField from '@mui/material/TextField';
// ----------------------------------------------------------------------
type BoolFilterProps = {
type NumFilterProps = {
label: string;
onChange?: (value: string) => void;
}
const isNumbers = (str: string) => /^[0-9]*$/.test(str);
export function IntFilter({ label }: BoolFilterProps) {
export function IntFilter({ label, onChange }: NumFilterProps) {
const [val, setVal] = useState("");
const onInputChange = (event: any) => {
const value = event.target.value;
if (isNumbers(value)) {
setVal(value);
debouncedChange(value);
}
};
const debouncedChange = useMemo(() =>
debounce((value: string) => {
onChange?.(value);
}, 1000)
, [onChange]);
return <TextField label={label} value={val} onChange={onInputChange} variant="filled" />;
}
export function DecimalFilter({ label }: BoolFilterProps) {
return <TextField type="number" label={label} variant="filled" />;
export function DecimalFilter({ label, onChange }: NumFilterProps) {
const debouncedChange = useMemo(() =>
debounce((value: string) => {
onChange?.(value);
}, 1000)
, [onChange]);
return <TextField type="number" label={label} variant="filled" onChange={e => debouncedChange(e.target.value)} />;
}

View File

@@ -1,10 +1,20 @@
import { useMemo } from 'react';
import debounce from 'lodash.debounce';
import TextField from '@mui/material/TextField';
// ----------------------------------------------------------------------
type TextFilterProps = {
label: string;
onChange?: (value: string) => void;
}
export function TextFilter({ label }: TextFilterProps) {
return <TextField label={label} variant="filled" />;
export function TextFilter({ label, onChange }: TextFilterProps) {
const debouncedChange = useMemo(() =>
debounce((value: string) => {
onChange?.(value);
}, 1000)
, [onChange]);
return <TextField label={label} variant="filled" onChange={e => debouncedChange(e.target.value)} />;
}

View File

@@ -8,7 +8,7 @@ import Autocomplete from '@mui/material/Autocomplete';
import { Iconify } from 'src/components/iconify/iconify';
import { createAttributes, filterTypes, Type } from '../../../api/attribute-service';
import { createAttributes, filterTypes, Type } from '../../../services/attribute-service';
const style = {
position: 'absolute',

View File

@@ -1,13 +1,33 @@
import { useState } from 'react';
import { useEffect, useState } from 'react';
import Box from '@mui/material/Box';
import Modal from '@mui/material/Modal';
import { TextField } from '@mui/material';
import { Type } from 'src/api/attribute-service';
import { FileFormat } from 'src/services/document-service';
const getMimeType = (format: FileFormat): string => {
switch (format) {
case 'pdf': return 'application/pdf';
case 'docx': return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
case 'xlsx': return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
case 'csv': return 'text/csv';
case 'pptx': return 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
case 'txt': return 'text/plain';
case 'json': return 'application/json';
case 'xml': return 'application/xml';
case 'html': return 'text/html';
case 'jpg': return 'image/jpeg';
case 'png': return 'image/png';
case 'svg': return 'image/svg+xml';
case 'zip': return 'application/zip';
case 'md': return 'text/markdown';
default: return 'application/octet-stream';
}
};
type DocFullViewProps = {
data: Uint8Array;
data: Uint8Array | Promise<Uint8Array>;
format: FileFormat;
open: boolean;
handleClose: () => void;
}
@@ -17,28 +37,86 @@ const style = {
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
width: '90%',
height: '90%',
bgcolor: 'transparent',
};
export default function DocFullView({ data, open, handleClose }: DocFullViewProps) {
const [name, setName] = useState<string | undefined>('');
const [label, setLabel] = useState<string | undefined>('');
const [selectedType, setSelectedType] = useState<Type | null>(null);
export default function DocFullView({ data, format, open, handleClose }: DocFullViewProps) {
const [objectUrl, setObjectUrl] = useState<string | null>(null);
useEffect(() => {
let isMounted = true;
let url: string | null = null;
const processData = async () => {
try {
const resolvedData = await data;
const mimeType = getMimeType(format);
const blob = new Blob([resolvedData], { type: mimeType });
url = URL.createObjectURL(blob);
if (isMounted) {
setObjectUrl(url);
}
} catch (err) {
console.error('Data resolution error:', err);
}
};
processData();
return () => {
isMounted = false;
if (url) {
URL.revokeObjectURL(url);
}
};
}, [data, format]);
const renderContent = () => {
if (!objectUrl || !format) return null;
if (['pdf', 'html', 'txt', 'json', 'xml', 'md'].includes(format)) {
return (
<iframe
src={objectUrl}
style={{ width: '100%', height: '100%', border: 'none' }}
title={`Viewer for ${format}`}
/>
);
}
if (['jpg', 'png', 'svg'].includes(format)) {
return (
<img
src={objectUrl}
alt="Document Preview"
style={{ maxWidth: '100%', maxHeight: '100%' }}
/>
);
}
// Download link for unsupported preview formats
style.bgcolor = 'lightgray'
return (
<Box textAlign="center">
<p>Dieser Dateityp kann nicht angezeigt werden. Sie können es unten herunterladen:</p>
<a href={objectUrl} download={`document.${format}`}>Datei herunterladen</a>
</Box>
);
};
return (
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
<TextField label="Label" variant="filled" value={name} onChange={e => setName(e.target.value)} />
<TextField label="Name" variant="filled" value={label} onChange={e => setLabel(e.target.value)} />
{renderContent()}
</Box>
</Modal>
);
}
}

View File

@@ -6,9 +6,9 @@ import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
import Pagination from '@mui/material/Pagination';
import { Doc } from 'src/api/document-service';
import { DashboardContent } from 'src/layouts/dashboard';
import { Filter, getAttributes } from 'src/api/attribute-service';
import docService, { Doc } from 'src/services/document-service';
import { Attribute, getAttributes } from 'src/services/attribute-service';
import { Iconify } from 'src/components/iconify';
@@ -20,14 +20,10 @@ import { DecimalFilter, IntFilter } from '../num-filter';
import { DateFilter, DateTimeFilter, TimeFilter } from '../date-filter';
// ----------------------------------------------------------------------
type Props = {
docs: Doc[];
};
export function DocSearchView({ docs }: Props) {
export function DocSearchView() {
const [sortBy, setSortBy] = useState('latest');
const [filters, setFilters] = useState<Filter[]>([])
const [filters, setFilters] = useState<Attribute[]>([])
const handleSort = useCallback((newSort: string) => {
setSortBy(newSort);
@@ -41,6 +37,43 @@ export function DocSearchView({ docs }: Props) {
const [openCreateFilterModal, setOpenCreateFilterModal] = useState(false);
const [docs, setDocs] = useState<Doc[]>([]);
useEffect(() => {
docService.get({}).then((res) => {
setDocs(res);
});
}, []);
//#region attributes
const [attributes, setAttributes] = useState<Record<string, string>>({});
useEffect(() => {
docService.getByAttribute(attributes).then(setDocs);
}, [attributes]);
function setAttribute(name: string, serilizedValue: string) {
setAttributes(prev => ({
...prev,
[name]: serilizedValue
}));
}
function removeAttribute(name: string) {
setAttributes(prev => {
const { [name]: _, ...rest } = prev;
return rest;
});
}
function updateAttribute(name: string, serilizedValue?: string | null) {
if (serilizedValue)
setAttribute(name, serilizedValue);
else
removeAttribute(name);
}
//#endregion
//#region example components
// <Box
// sx={{
@@ -98,13 +131,13 @@ export function DocSearchView({ docs }: Props) {
filterComp = <BoolFilter label={filter.label ?? filter.name} />
break;
case 'INTEGER':
filterComp = <IntFilter label={filter.label ?? filter.name} />
filterComp = <IntFilter label={filter.label ?? filter.name} onChange={value => updateAttribute(filter.name, value)} />
break;
case 'DECIMAL':
filterComp = <DecimalFilter label={filter.label ?? filter.name} />
filterComp = <DecimalFilter label={filter.label ?? filter.name} onChange={value => updateAttribute(filter.name, value)} />
break;
case 'VARCHAR':
filterComp = <TextFilter label={filter.label ?? filter.name} />
filterComp = <TextFilter label={filter.label ?? filter.name} onChange={value => updateAttribute(filter.name, value)} />
break;
case 'DATE':
filterComp = <DateFilter label={filter.label ?? filter.name} />

View File

@@ -22,6 +22,8 @@ type Props = CardProps & {
percent: number;
color?: PaletteColorKey;
icon: React.ReactNode;
details?: { label: string; value: number }[];
loading?: boolean;
chart: {
series: number[];
categories: string[];
@@ -37,6 +39,8 @@ export function AnalyticsWidgetSummary({
chart,
percent,
color = 'primary',
details,
loading = false,
...other
}: Props) {
const theme = useTheme();
@@ -114,6 +118,23 @@ export function AnalyticsWidgetSummary({
<Box sx={{ mb: 1, typography: 'subtitle2' }}>{title}</Box>
<Box sx={{ typography: 'h4' }}>{fShortenNumber(total)}</Box>
{details?.length ? (
<Box component="ul" sx={{ mt: 1.5, mb: 0, pl: 0, listStyle: 'none', gap: 0.5, display: 'grid' }}>
{details.map((item) => (
<Box
component="li"
key={item.label}
sx={{ display: 'flex', justifyContent: 'space-between', typography: 'caption', color: 'text.secondary' }}
>
<Box component="span">{item.label}</Box>
<Box component="span" sx={{ color: 'text.primary', fontWeight: 'fontWeightSemiBold' }}>
{loading ? '…' : fShortenNumber(item.value)}
</Box>
</Box>
))}
</Box>
) : null}
</Box>
<Chart

View File

@@ -1,8 +1,11 @@
import { useMemo, useState, useEffect } from 'react';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import { DashboardContent } from 'src/layouts/dashboard';
import { _posts, _tasks, _traffic, _timeline } from 'src/_mock';
import { fetchFileStatsToday } from 'src/services/file-stats-service';
import { AnalyticsNews } from '../analytics-news';
import { AnalyticsTasks } from '../analytics-tasks';
@@ -17,6 +20,61 @@ import { AnalyticsConversionRates } from '../analytics-conversion-rates';
// ----------------------------------------------------------------------
export function OverviewAnalyticsView() {
const [fileStats, setFileStats] = useState({ filed: 0, edited: 0 });
const [loadingFiles, setLoadingFiles] = useState(true);
const visitCategories = useMemo(() => {
const days = ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'];
const today = new Date();
const labels = Array.from({ length: 7 }, (_, idx) => {
const d = new Date(today);
d.setDate(today.getDate() - (6 - idx));
const dayIdx = d.getDay();
return days[dayIdx];
});
labels[labels.length - 1] = 'Heute';
return labels;
}, []);
const baselineFiled = [43, 33, 22, 37, 67, 68];
const baselineEdited = [51, 70, 47, 67, 40, 37];
const visitSeries = [
{
name: 'Dateien abgelegt',
data: [...baselineFiled, fileStats.filed],
},
{
name: 'Dateien bearbeitet',
data: [...baselineEdited, fileStats.edited],
},
];
const envelopeStats = {
fullySigned: 140,
partiallySigned: 68,
declined: 26,
};
const envelopeTotal = envelopeStats.fullySigned + envelopeStats.partiallySigned + envelopeStats.declined;
useEffect(() => {
let active = true;
fetchFileStatsToday()
.then((data) => {
if (active) setFileStats(data);
})
.finally(() => {
if (active) setLoadingFiles(false);
});
return () => {
active = false;
};
}, []);
return (
<DashboardContent maxWidth="xl">
<Typography variant="h4" sx={{ mb: { xs: 3, md: 5 } }}>
@@ -26,13 +84,19 @@ export function OverviewAnalyticsView() {
<Grid container spacing={3}>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<AnalyticsWidgetSummary
title="Weekly sales"
percent={2.6}
total={714000}
icon={<img alt="Weekly sales" src="/assets/icons/glass/ic-glass-bag.svg" />}
title="Dateien - Heute"
percent={0}
total={fileStats.filed + fileStats.edited}
icon={<img alt="Dateien" src="/assets/icons/glass/ic-glass-bag.svg" />}
details={[
{ label: 'Dateien abgelegt', value: fileStats.filed },
{ label: 'Dateien bearbeitet', value: fileStats.edited },
]}
loading={loadingFiles}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [22, 8, 35, 50, 82, 84, 77, 12],
categories: ['Heute'],
series: [fileStats.filed, fileStats.edited],
options: { stroke: { width: 2 } },
}}
/>
</Grid>
@@ -67,15 +131,29 @@ export function OverviewAnalyticsView() {
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<AnalyticsWidgetSummary
title="Messages"
title="Envelopes versendet"
percent={3.6}
total={234}
total={envelopeTotal}
color="error"
icon={<img alt="Messages" src="/assets/icons/glass/ic-glass-message.svg" />}
icon={<img alt="Envelopes versendet" src="/assets/icons/glass/ic-glass-message.svg" />}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [56, 30, 23, 54, 47, 40, 62, 73],
categories: ['Vollständig signiert', 'Teilsigniert', 'Abgelehnt'],
series: [envelopeStats.fullySigned, envelopeStats.partiallySigned, envelopeStats.declined],
}}
details={[
{
label: 'Vollständig signiert',
value: envelopeStats.fullySigned,
},
{
label: 'Teilsigniert',
value: envelopeStats.partiallySigned,
},
{
label: 'Abgelehnt',
value: envelopeStats.declined,
},
]}
/>
</Grid>
@@ -95,14 +173,14 @@ export function OverviewAnalyticsView() {
<Grid size={{ xs: 12, md: 6, lg: 8 }}>
<AnalyticsWebsiteVisits
title="Website visits"
subheader="(+43%) than last year"
title="Dateien verarbeitet"
subheader="(+43%) als letzte Woche"
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'],
series: [
{ name: 'Team A', data: [43, 33, 22, 37, 67, 68, 37, 24, 55] },
{ name: 'Team B', data: [51, 70, 47, 67, 40, 37, 24, 70, 24] },
],
categories: visitCategories,
series: visitSeries,
options: {
tooltip: { y: { formatter: (value: number) => `${value} Dateien` } },
},
}}
/>
</Grid>

View File

@@ -8,7 +8,7 @@ import Typography from '@mui/material/Typography';
import { fCurrency } from 'src/utils/format-number';
import { Product } from 'src/api/product-service';
import { Product } from 'src/services/product-service';
import { Label } from 'src/components/label';
import { ColorPreview } from 'src/components/color-utils';

View File

@@ -7,7 +7,7 @@ import Typography from '@mui/material/Typography';
import { _products } from 'src/_mock';
import { DashboardContent } from 'src/layouts/dashboard';
import { getProductsAsync, Product } from 'src/api/product-service';
import { getProductsAsync, Product } from 'src/services/product-service';
import { ProductSort } from '../product-sort';
import { ProductItem } from '../product-item';

View File

@@ -1,4 +1,4 @@
import { _filters } from 'src/_mock/_data';
import { _attributes } from 'src/_mock/_data';
export type Type = 'BOOLEAN' | 'DATE' | 'TIME' | 'DATETIME' | 'VARCHAR' | 'INTEGER' | 'DECIMAL';
@@ -18,19 +18,19 @@ export type AttributeCreateDto = {
type: Type;
};
export type Filter = AttributeCreateDto & {
export type Attribute = AttributeCreateDto & {
id: number;
};
export function getAttributes(): Promise<Filter[]> {
return Promise.resolve(_filters);
export function getAttributes(): Promise<Attribute[]> {
return Promise.resolve(_attributes);
}
export function createAttributes(filter: AttributeCreateDto): Promise<Filter> {
const newFilter: Filter = {
export function createAttributes(filter: AttributeCreateDto): Promise<Attribute> {
const newFilter: Attribute = {
...filter,
id: _filters.length + 1
id: _attributes.length + 1
};
_filters.push(newFilter);
_attributes.push(newFilter);
return Promise.resolve(newFilter);
}

View File

@@ -0,0 +1,114 @@
import { _documents, _genFile } from "src/_mock"
export type FileFormat =
| 'pdf'
| 'docx'
| 'xlsx'
| 'csv'
| 'pptx'
| 'txt'
| 'json'
| 'xml'
| 'html'
| 'jpg'
| 'png'
| 'svg'
| 'zip'
| 'md';
const validExtensions: FileFormat[] = [
'pdf', 'docx', 'xlsx', 'csv', 'pptx',
'txt', 'json', 'xml', 'html', 'jpg',
'png', 'svg', 'zip', 'md'
];
type DocAttribute = {
name: string;
serilizedValue: string;
}
export class Doc {
static map(source?: Partial<Doc>): Doc {
const doc = new Doc();
Object.assign(doc, source);
return doc;
}
id!: number;
name!: string;
addedWhen!: Date;
addedWho!: string;
changedWhen?: Date;
changedWho?: string;
attributes: Array<DocAttribute> = [];
get data(): Promise<Uint8Array> {
return Promise.resolve(_genFile(this.name)!);
}
getChangedInfo(separator: string = " | "): string | null {
const who = this.changedWho?.trim();
const when = this.changedWhen?.toLocaleDateString('de-DE');
if (!who && !when) {
return null;
}
return [who, when].filter(Boolean).join(separator);
}
get extension(): FileFormat {
const parts = this.name.split('.');
if (parts.length > 1 && parts[parts.length - 1].trim() !== '') {
const ext = parts[parts.length - 1].toLowerCase();
if (validExtensions.includes(ext as FileFormat))
return ext as FileFormat;
}
throw new Error(`Invalid or missing file extension in filename: "${this.name}". Supported extensions are: ${validExtensions.join(', ')}.`);
}
get iconSrc(): string {
return `assets/icons/file/${this.extension ?? 'unknown'}.svg`;
}
}
export type DocQuery = {
id?: number | undefined,
name?: string | undefined,
attributes?: Record<string, string>
}
class DocService {
get(query: DocQuery | undefined = undefined): Promise<Doc[]> {
let documents = _documents;
if (query?.id)
documents = documents.filter(d => d.id === query.id);
if (query?.name)
documents = documents.filter(d => d.name === query.name);
for (const name in query?.attributes) {
const attr = query.attributes[name];
documents = documents.filter(d => d.attributes.find(a => a.name === name)?.serilizedValue.toLowerCase().includes(attr.toLowerCase()));
}
return Promise.resolve(documents);
}
getById(id: number): Promise<Doc[]> {
return this.get({ id: id });
}
getByName(name: string): Promise<Doc[]> {
return this.get({ name: name });
}
getByAttribute(attributes: Record<string, string>): Promise<Doc[]> {
return this.get({ attributes: attributes });
}
}
export default new DocService();

View File

@@ -0,0 +1,19 @@
export type FileStatsToday = {
filed: number;
edited: number;
};
export async function fetchFilesAbgelegtToday(): Promise<number> {
// Mock placeholder: returns number of files placed today
return Promise.resolve(5);
}
export async function fetchFilesBearbeitetToday(): Promise<number> {
// Mock placeholder: returns number of files edited today
return Promise.resolve(20);
}
export async function fetchFileStatsToday(): Promise<FileStatsToday> {
const [filed, edited] = await Promise.all([fetchFilesAbgelegtToday(), fetchFilesBearbeitetToday()]);
return { filed, edited };
}

View File

@@ -42,7 +42,7 @@ const MuiCard: Components<Theme>['MuiCard'] = {
zIndex: 0,
position: 'relative',
boxShadow: theme.vars.customShadows.card,
borderRadius: theme.shape.borderRadius * 2,
borderRadius: theme.shape.borderRadius as any * 2,
}),
},
};

View File

@@ -47,10 +47,10 @@
dependencies:
"@babel/types" "^7.27.0"
"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.26.10", "@babel/runtime@^7.27.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
version "7.27.6"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz"
integrity sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==
"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.26.10", "@babel/runtime@^7.27.6", "@babel/runtime@^7.28.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
version "7.28.4"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz"
integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==
"@babel/template@^7.27.0":
version "7.27.0"
@@ -157,10 +157,10 @@
resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz"
integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==
"@emotion/styled@^11.14.0", "@emotion/styled@^11.3.0", "@emotion/styled@^11.8.1":
version "11.14.0"
resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz"
integrity sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==
"@emotion/styled@^11.14.1", "@emotion/styled@^11.3.0", "@emotion/styled@^11.8.1":
version "11.14.1"
resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz"
integrity sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==
dependencies:
"@babel/runtime" "^7.18.3"
"@emotion/babel-plugin" "^11.13.5"
@@ -194,10 +194,10 @@
resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz"
integrity sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
version "4.5.1"
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz"
integrity sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==
"@eslint-community/eslint-utils@^4.4.0", "@eslint-community/eslint-utils@^4.8.0":
version "4.9.0"
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz"
integrity sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==
dependencies:
eslint-visitor-keys "^3.4.3"
@@ -206,31 +206,26 @@
resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz"
integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
"@eslint/config-array@^0.19.2":
version "0.19.2"
resolved "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz"
integrity sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==
"@eslint/config-array@^0.21.1":
version "0.21.1"
resolved "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz"
integrity sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==
dependencies:
"@eslint/object-schema" "^2.1.6"
"@eslint/object-schema" "^2.1.7"
debug "^4.3.1"
minimatch "^3.1.2"
"@eslint/config-helpers@^0.2.0":
version "0.2.1"
resolved "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz"
integrity sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==
"@eslint/core@^0.12.0":
version "0.12.0"
resolved "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz"
integrity sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==
"@eslint/config-helpers@^0.4.2":
version "0.4.2"
resolved "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz"
integrity sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==
dependencies:
"@types/json-schema" "^7.0.15"
"@eslint/core" "^0.17.0"
"@eslint/core@^0.13.0":
version "0.13.0"
resolved "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz"
integrity sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==
"@eslint/core@^0.17.0":
version "0.17.0"
resolved "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz"
integrity sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==
dependencies:
"@types/json-schema" "^7.0.15"
@@ -249,22 +244,22 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@^9.23.0", "@eslint/js@9.23.0":
version "9.23.0"
resolved "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz"
integrity sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==
"@eslint/js@^9.23.0", "@eslint/js@9.39.1":
version "9.39.1"
resolved "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz"
integrity sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==
"@eslint/object-schema@^2.1.6":
version "2.1.6"
resolved "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz"
integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==
"@eslint/object-schema@^2.1.7":
version "2.1.7"
resolved "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz"
integrity sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==
"@eslint/plugin-kit@^0.2.7":
version "0.2.8"
resolved "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz"
integrity sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==
"@eslint/plugin-kit@^0.4.1":
version "0.4.1"
resolved "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz"
integrity sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==
dependencies:
"@eslint/core" "^0.13.0"
"@eslint/core" "^0.17.0"
levn "^0.4.1"
"@fontsource-variable/dm-sans@^5.2.5":
@@ -349,17 +344,17 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
"@mui/core-downloads-tracker@^7.2.0":
version "7.2.0"
resolved "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.2.0.tgz"
integrity sha512-d49s7kEgI5iX40xb2YPazANvo7Bx0BLg/MNRwv+7BVpZUzXj1DaVCKlQTDex3gy/0jsCb4w7AY2uH4t4AJvSog==
"@mui/core-downloads-tracker@^7.3.5":
version "7.3.5"
resolved "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.5.tgz"
integrity sha512-kOLwlcDPnVz2QMhiBv0OQ8le8hTCqKM9cRXlfVPL91l3RGeOsxrIhNRsUt3Xb8wb+pTVUolW+JXKym93vRKxCw==
"@mui/icons-material@^7.2.0":
version "7.2.0"
resolved "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.2.0.tgz"
integrity sha512-gRCspp3pfjHQyTmSOmYw7kUQTd9Udpdan4R8EnZvqPeoAtHnPzkvjBrBqzKaoAbbBp5bGF7BcD18zZJh4nwu0A==
"@mui/icons-material@^7.3.5":
version "7.3.5"
resolved "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.5.tgz"
integrity sha512-LciL1GLMZ+VlzyHAALSVAR22t8IST4LCXmljcUSx2NOutgO2XnxdIp8ilFbeNf9wpo0iUFbAuoQcB7h+HHIf3A==
dependencies:
"@babel/runtime" "^7.27.6"
"@babel/runtime" "^7.28.4"
"@mui/lab@^7.0.0-beta.10":
version "7.0.0-beta.10"
@@ -373,77 +368,77 @@
clsx "^2.1.1"
prop-types "^15.8.1"
"@mui/material@^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/material@^7.0.1", "@mui/material@^7.2.0":
version "7.2.0"
resolved "https://registry.npmjs.org/@mui/material/-/material-7.2.0.tgz"
integrity sha512-NTuyFNen5Z2QY+I242MDZzXnFIVIR6ERxo7vntFi9K1wCgSwvIl0HcAO2OOydKqqKApE6omRiYhpny1ZhGuH7Q==
"@mui/material@^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/material@^7.0.1", "@mui/material@^7.3.5":
version "7.3.5"
resolved "https://registry.npmjs.org/@mui/material/-/material-7.3.5.tgz"
integrity sha512-8VVxFmp1GIm9PpmnQoCoYo0UWHoOrdA57tDL62vkpzEgvb/d71Wsbv4FRg7r1Gyx7PuSo0tflH34cdl/NvfHNQ==
dependencies:
"@babel/runtime" "^7.27.6"
"@mui/core-downloads-tracker" "^7.2.0"
"@mui/system" "^7.2.0"
"@mui/types" "^7.4.4"
"@mui/utils" "^7.2.0"
"@babel/runtime" "^7.28.4"
"@mui/core-downloads-tracker" "^7.3.5"
"@mui/system" "^7.3.5"
"@mui/types" "^7.4.8"
"@mui/utils" "^7.3.5"
"@popperjs/core" "^2.11.8"
"@types/react-transition-group" "^4.4.12"
clsx "^2.1.1"
csstype "^3.1.3"
prop-types "^15.8.1"
react-is "^19.1.0"
react-is "^19.2.0"
react-transition-group "^4.4.5"
"@mui/private-theming@^7.2.0":
version "7.2.0"
resolved "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.2.0.tgz"
integrity sha512-y6N1Yt3T5RMxVFnCh6+zeSWBuQdNDm5/UlM0EAYZzZR/1u+XKJWYQmbpx4e+F+1EpkYi3Nk8KhPiQDi83M3zIw==
"@mui/private-theming@^7.3.5":
version "7.3.5"
resolved "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.5.tgz"
integrity sha512-cTx584W2qrLonwhZLbEN7P5pAUu0nZblg8cLBlTrZQ4sIiw8Fbvg7GvuphQaSHxPxrCpa7FDwJKtXdbl2TSmrA==
dependencies:
"@babel/runtime" "^7.27.6"
"@mui/utils" "^7.2.0"
"@babel/runtime" "^7.28.4"
"@mui/utils" "^7.3.5"
prop-types "^15.8.1"
"@mui/styled-engine@^7.2.0":
version "7.2.0"
resolved "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.2.0.tgz"
integrity sha512-yq08xynbrNYcB1nBcW9Fn8/h/iniM3ewRguGJXPIAbHvxEF7Pz95kbEEOAAhwzxMX4okhzvHmk0DFuC5ayvgIQ==
"@mui/styled-engine@^7.3.5":
version "7.3.5"
resolved "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.5.tgz"
integrity sha512-zbsZ0uYYPndFCCPp2+V3RLcAN6+fv4C8pdwRx6OS3BwDkRCN8WBehqks7hWyF3vj1kdQLIWrpdv/5Y0jHRxYXQ==
dependencies:
"@babel/runtime" "^7.27.6"
"@babel/runtime" "^7.28.4"
"@emotion/cache" "^11.14.0"
"@emotion/serialize" "^1.3.3"
"@emotion/sheet" "^1.4.0"
csstype "^3.1.3"
prop-types "^15.8.1"
"@mui/system@^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/system@^7.0.1", "@mui/system@^7.2.0":
version "7.2.0"
resolved "https://registry.npmjs.org/@mui/system/-/system-7.2.0.tgz"
integrity sha512-PG7cm/WluU6RAs+gNND2R9vDwNh+ERWxPkqTaiXQJGIFAyJ+VxhyKfzpdZNk0z0XdmBxxi9KhFOpgxjehf/O0A==
"@mui/system@^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/system@^7.0.1", "@mui/system@^7.3.5":
version "7.3.5"
resolved "https://registry.npmjs.org/@mui/system/-/system-7.3.5.tgz"
integrity sha512-yPaf5+gY3v80HNkJcPi6WT+r9ebeM4eJzrREXPxMt7pNTV/1eahyODO4fbH3Qvd8irNxDFYn5RQ3idHW55rA6g==
dependencies:
"@babel/runtime" "^7.27.6"
"@mui/private-theming" "^7.2.0"
"@mui/styled-engine" "^7.2.0"
"@mui/types" "^7.4.4"
"@mui/utils" "^7.2.0"
"@babel/runtime" "^7.28.4"
"@mui/private-theming" "^7.3.5"
"@mui/styled-engine" "^7.3.5"
"@mui/types" "^7.4.8"
"@mui/utils" "^7.3.5"
clsx "^2.1.1"
csstype "^3.1.3"
prop-types "^15.8.1"
"@mui/types@^7.4.0", "@mui/types@^7.4.4":
version "7.4.4"
resolved "https://registry.npmjs.org/@mui/types/-/types-7.4.4.tgz"
integrity sha512-p63yhbX52MO/ajXC7hDHJA5yjzJekvWD3q4YDLl1rSg+OXLczMYPvTuSuviPRCgRX8+E42RXz1D/dz9SxPSlWg==
"@mui/types@^7.4.0", "@mui/types@^7.4.8":
version "7.4.8"
resolved "https://registry.npmjs.org/@mui/types/-/types-7.4.8.tgz"
integrity sha512-ZNXLBjkPV6ftLCmmRCafak3XmSn8YV0tKE/ZOhzKys7TZXUiE0mZxlH8zKDo6j6TTUaDnuij68gIG+0Ucm7Xhw==
dependencies:
"@babel/runtime" "^7.27.6"
"@babel/runtime" "^7.28.4"
"@mui/utils@^7.0.1", "@mui/utils@^7.1.1", "@mui/utils@^7.2.0":
version "7.2.0"
resolved "https://registry.npmjs.org/@mui/utils/-/utils-7.2.0.tgz"
integrity sha512-O0i1GQL6MDzhKdy9iAu5Yr0Sz1wZjROH1o3aoztuivdCXqEeQYnEjTDiRLGuFxI9zrUbTHBwobMyQH5sNtyacw==
"@mui/utils@^7.0.1", "@mui/utils@^7.1.1", "@mui/utils@^7.3.5":
version "7.3.5"
resolved "https://registry.npmjs.org/@mui/utils/-/utils-7.3.5.tgz"
integrity sha512-jisvFsEC3sgjUjcPnR4mYfhzjCDIudttSGSbe1o/IXFNu0kZuR+7vqQI0jg8qtcVZBHWrwTfvAZj9MNMumcq1g==
dependencies:
"@babel/runtime" "^7.27.6"
"@mui/types" "^7.4.4"
"@babel/runtime" "^7.28.4"
"@mui/types" "^7.4.8"
"@types/prop-types" "^15.7.15"
clsx "^2.1.1"
prop-types "^15.8.1"
react-is "^19.1.0"
react-is "^19.2.0"
"@mui/x-date-pickers@^8.7.0":
version "8.7.0"
@@ -566,11 +561,6 @@
dependencies:
"@swc/counter" "^0.1.3"
"@types/cookie@^0.6.0":
version "0.6.0"
resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz"
integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==
"@types/estree@^1.0.6", "@types/estree@1.0.7":
version "1.0.7"
resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz"
@@ -586,6 +576,18 @@
resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
"@types/lodash.debounce@^4.0.9":
version "4.0.9"
resolved "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz"
integrity sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==
dependencies:
"@types/lodash" "*"
"@types/lodash@*":
version "4.17.20"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz"
integrity sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==
"@types/node@^18.0.0 || ^20.0.0 || >=22.0.0", "@types/node@^22.14.0":
version "22.14.0"
resolved "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz"
@@ -723,10 +725,10 @@ acorn-jsx@^5.3.2:
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.14.0:
version "8.14.1"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz"
integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.15.0:
version "8.15.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz"
integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
ajv@^6.12.4:
version "6.12.6"
@@ -883,17 +885,17 @@ balanced-match@^1.0.0:
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
version "1.1.12"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz"
integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
version "2.0.2"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz"
integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==
dependencies:
balanced-match "^1.0.0"
@@ -1366,10 +1368,10 @@ eslint-plugin-unused-imports@^4.1.4:
resolved "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz"
integrity sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==
eslint-scope@^8.3.0:
version "8.3.0"
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz"
integrity sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==
eslint-scope@^8.4.0:
version "8.4.0"
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz"
integrity sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
@@ -1379,37 +1381,36 @@ eslint-visitor-keys@^3.4.3:
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
eslint-visitor-keys@^4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz"
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
eslint-visitor-keys@^4.2.0, eslint-visitor-keys@^4.2.1:
version "4.2.1"
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz"
integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==
eslint@*, "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.57.0 || ^9.0.0", "eslint@^9.0.0 || ^8.0.0", eslint@^9.23.0, eslint@>=7, eslint@>=8.45.0:
version "9.23.0"
resolved "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz"
integrity sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==
version "9.39.1"
resolved "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz"
integrity sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/eslint-utils" "^4.8.0"
"@eslint-community/regexpp" "^4.12.1"
"@eslint/config-array" "^0.19.2"
"@eslint/config-helpers" "^0.2.0"
"@eslint/core" "^0.12.0"
"@eslint/config-array" "^0.21.1"
"@eslint/config-helpers" "^0.4.2"
"@eslint/core" "^0.17.0"
"@eslint/eslintrc" "^3.3.1"
"@eslint/js" "9.23.0"
"@eslint/plugin-kit" "^0.2.7"
"@eslint/js" "9.39.1"
"@eslint/plugin-kit" "^0.4.1"
"@humanfs/node" "^0.16.6"
"@humanwhocodes/module-importer" "^1.0.1"
"@humanwhocodes/retry" "^0.4.2"
"@types/estree" "^1.0.6"
"@types/json-schema" "^7.0.15"
ajv "^6.12.4"
chalk "^4.0.0"
cross-spawn "^7.0.6"
debug "^4.3.2"
escape-string-regexp "^4.0.0"
eslint-scope "^8.3.0"
eslint-visitor-keys "^4.2.0"
espree "^10.3.0"
eslint-scope "^8.4.0"
eslint-visitor-keys "^4.2.1"
espree "^10.4.0"
esquery "^1.5.0"
esutils "^2.0.2"
fast-deep-equal "^3.1.3"
@@ -1425,14 +1426,14 @@ eslint@*, "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9", "eslint@^3
natural-compare "^1.4.0"
optionator "^0.9.3"
espree@^10.0.1, espree@^10.3.0:
version "10.3.0"
resolved "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz"
integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==
espree@^10.0.1, espree@^10.4.0:
version "10.4.0"
resolved "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz"
integrity sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==
dependencies:
acorn "^8.14.0"
acorn "^8.15.0"
acorn-jsx "^5.3.2"
eslint-visitor-keys "^4.2.0"
eslint-visitor-keys "^4.2.1"
esquery@^1.5.0:
version "1.6.0"
@@ -1491,10 +1492,10 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
fdir@^6.4.3:
version "6.4.3"
resolved "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz"
integrity sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==
fdir@^6.4.4, fdir@^6.5.0:
version "6.5.0"
resolved "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz"
integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==
file-entry-cache@^8.0.0:
version "8.0.0"
@@ -1946,9 +1947,9 @@ iterator.prototype@^1.1.4:
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
version "4.1.1"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz"
integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==
dependencies:
argparse "^2.0.1"
@@ -2021,6 +2022,11 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz"
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
@@ -2263,10 +2269,10 @@ picomatch@^2.3.1:
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
"picomatch@^3 || ^4", picomatch@^4.0.2:
version "4.0.2"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz"
integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
"picomatch@^3 || ^4", picomatch@^4.0.2, picomatch@^4.0.3:
version "4.0.3"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz"
integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==
possible-typed-array-names@^1.0.0:
version "1.1.0"
@@ -2335,27 +2341,25 @@ react-is@^16.7.0:
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^19.1.0:
version "19.1.0"
resolved "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz"
integrity sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==
react-is@^19.2.0:
version "19.2.0"
resolved "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz"
integrity sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==
react-router-dom@^7.4.1:
version "7.4.1"
resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.4.1.tgz"
integrity sha512-L3/4tig0Lvs6m6THK0HRV4eHUdpx0dlJasgCxXKnavwhh4tKYgpuZk75HRYNoRKDyDWi9QgzGXsQ1oQSBlWpAA==
version "7.9.6"
resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.6.tgz"
integrity sha512-2MkC2XSXq6HjGcihnx1s0DBWQETI4mlis4Ux7YTLvP67xnGxCvq+BcCQSO81qQHVUTM1V53tl4iVVaY5sReCOA==
dependencies:
react-router "7.4.1"
react-router "7.9.6"
react-router@7.4.1:
version "7.4.1"
resolved "https://registry.npmjs.org/react-router/-/react-router-7.4.1.tgz"
integrity sha512-Vmizn9ZNzxfh3cumddqv3kLOKvc7AskUT0dC1prTabhiEi0U4A33LmkDOJ79tXaeSqCqMBXBU/ySX88W85+EUg==
react-router@7.9.6:
version "7.9.6"
resolved "https://registry.npmjs.org/react-router/-/react-router-7.9.6.tgz"
integrity sha512-Y1tUp8clYRXpfPITyuifmSoE2vncSME18uVLgaqyxh9H35JWpIfzHo+9y3Fzh5odk/jxPW29IgLgzcdwxGqyNA==
dependencies:
"@types/cookie" "^0.6.0"
cookie "^1.0.1"
set-cookie-parser "^2.6.0"
turbo-stream "2.4.0"
react-transition-group@^4.4.5:
version "4.4.5"
@@ -2441,7 +2445,7 @@ reusify@^1.0.4:
resolved "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz"
integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==
rollup@^4.30.1:
rollup@^4.34.9:
version "4.39.0"
resolved "https://registry.npmjs.org/rollup/-/rollup-4.39.0.tgz"
integrity sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==
@@ -2521,9 +2525,9 @@ semver@^7.6.0, semver@^7.7.1:
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
set-cookie-parser@^2.6.0:
version "2.7.1"
resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz"
integrity sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==
version "2.7.2"
resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz"
integrity sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==
set-function-length@^1.2.2:
version "1.2.2"
@@ -2735,13 +2739,13 @@ tiny-invariant@^1.3.3:
resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz"
integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
tinyglobby@^0.2.12:
version "0.2.12"
resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz"
integrity sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==
tinyglobby@^0.2.12, tinyglobby@^0.2.13:
version "0.2.15"
resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz"
integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==
dependencies:
fdir "^6.4.3"
picomatch "^4.0.2"
fdir "^6.5.0"
picomatch "^4.0.3"
to-regex-range@^5.0.1:
version "5.0.1"
@@ -2765,11 +2769,6 @@ tsconfig-paths@^3.15.0:
minimist "^1.2.6"
strip-bom "^3.0.0"
turbo-stream@2.4.0:
version "2.4.0"
resolved "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz"
integrity sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
@@ -2900,13 +2899,16 @@ vite-plugin-checker@^0.9.1:
vscode-uri "^3.1.0"
"vite@^4 || ^5 || ^6", vite@^6.2.5, vite@>=2.0.0:
version "6.2.5"
resolved "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz"
integrity sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==
version "6.4.1"
resolved "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz"
integrity sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==
dependencies:
esbuild "^0.25.0"
fdir "^6.4.4"
picomatch "^4.0.2"
postcss "^8.5.3"
rollup "^4.30.1"
rollup "^4.34.9"
tinyglobby "^0.2.13"
optionalDependencies:
fsevents "~2.3.3"
@@ -2985,11 +2987,6 @@ yaml@^1.10.0:
resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yaml@^2.4.2:
version "2.7.1"
resolved "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz"
integrity sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"