feat(users): add roles page and add, edit, delete , toggle ,reset password functionality

This commit is contained in:
ghazall-ag
2025-11-07 14:24:09 +03:30
parent 06d430d21c
commit fc229cad99
35 changed files with 4836 additions and 858 deletions

12
node_modules/.package-lock.json generated vendored
View File

@@ -3907,6 +3907,18 @@
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-toastify": {
"version": "11.0.5",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.5.tgz",
"integrity": "sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==",
"dependencies": {
"clsx": "^2.1.1"
},
"peerDependencies": {
"react": "^18 || ^19",
"react-dom": "^18 || ^19"
}
},
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",

View File

@@ -1,69 +1,78 @@
{
"hash": "ff6fda40",
"browserHash": "c03c03c2",
"hash": "5dc29ded",
"browserHash": "8decdfc6",
"optimized": {
"react/jsx-runtime": {
"src": "../../react/jsx-runtime.js",
"file": "react_jsx-runtime.js",
"fileHash": "e8b04feb",
"fileHash": "071542c9",
"needsInterop": true
},
"react/jsx-dev-runtime": {
"src": "../../react/jsx-dev-runtime.js",
"file": "react_jsx-dev-runtime.js",
"fileHash": "778d2d19",
"fileHash": "2c0ef184",
"needsInterop": true
},
"react": {
"src": "../../react/index.js",
"file": "react.js",
"fileHash": "9085912a",
"fileHash": "97079daa",
"needsInterop": true
},
"axios": {
"src": "../../axios/index.js",
"file": "axios.js",
"fileHash": "387f77ed",
"fileHash": "89ede243",
"needsInterop": false
},
"lucide-react": {
"src": "../../lucide-react/dist/esm/lucide-react.mjs",
"file": "lucide-react.js",
"fileHash": "63623648",
"fileHash": "6ec5bbdf",
"needsInterop": false
},
"react-dom/client": {
"src": "../../react-dom/client.js",
"file": "react-dom_client.js",
"fileHash": "993544a9",
"fileHash": "cca5920c",
"needsInterop": true
},
"react-router-dom": {
"src": "../../react-router-dom/dist/index.js",
"file": "react-router-dom.js",
"fileHash": "d3f984dc",
"fileHash": "d17c5b44",
"needsInterop": false
},
"recharts": {
"src": "../../recharts/es6/index.js",
"file": "recharts.js",
"fileHash": "e1665e3e",
"fileHash": "93550599",
"needsInterop": false
},
"zustand": {
"src": "../../zustand/esm/index.mjs",
"file": "zustand.js",
"fileHash": "8be28924",
"fileHash": "80080d68",
"needsInterop": false
},
"zustand/middleware": {
"src": "../../zustand/esm/middleware.mjs",
"file": "zustand_middleware.js",
"fileHash": "936c3138",
"fileHash": "1fdb7da8",
"needsInterop": false
},
"react-toastify": {
"src": "../../react-toastify/dist/index.mjs",
"file": "react-toastify.js",
"fileHash": "af965fd8",
"needsInterop": false
}
},
"chunks": {
"chunk-YV3COZNF": {
"file": "chunk-YV3COZNF.js"
},
"chunk-ZXN67JHZ": {
"file": "chunk-ZXN67JHZ.js"
},

26
node_modules/.vite/deps/chunk-YV3COZNF.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
// node_modules/clsx/dist/clsx.mjs
function r(e) {
var t, f, n = "";
if ("string" == typeof e || "number" == typeof e)
n += e;
else if ("object" == typeof e)
if (Array.isArray(e)) {
var o = e.length;
for (t = 0; t < o; t++)
e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
} else
for (f in e)
e[f] && (n && (n += " "), n += f);
return n;
}
function clsx() {
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++)
(e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
return n;
}
var clsx_default = clsx;
export {
clsx_default
};
//# sourceMappingURL=chunk-YV3COZNF.js.map

7
node_modules/.vite/deps/chunk-YV3COZNF.js.map generated vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../clsx/dist/clsx.mjs"],
"sourcesContent": ["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;"],
"mappings": ";AAAA,SAAS,EAAE,GAAE;AAAC,MAAI,GAAE,GAAE,IAAE;AAAG,MAAG,YAAU,OAAO,KAAG,YAAU,OAAO;AAAE,SAAG;AAAA,WAAU,YAAU,OAAO;AAAE,QAAG,MAAM,QAAQ,CAAC,GAAE;AAAC,UAAI,IAAE,EAAE;AAAO,WAAI,IAAE,GAAE,IAAE,GAAE;AAAI,UAAE,CAAC,MAAI,IAAE,EAAE,EAAE,CAAC,CAAC,OAAK,MAAI,KAAG,MAAK,KAAG;AAAA,IAAE;AAAM,WAAI,KAAK;AAAE,UAAE,CAAC,MAAI,MAAI,KAAG,MAAK,KAAG;AAAG,SAAO;AAAC;AAAQ,SAAS,OAAM;AAAC,WAAQ,GAAE,GAAE,IAAE,GAAE,IAAE,IAAG,IAAE,UAAU,QAAO,IAAE,GAAE;AAAI,KAAC,IAAE,UAAU,CAAC,OAAK,IAAE,EAAE,CAAC,OAAK,MAAI,KAAG,MAAK,KAAG;AAAG,SAAO;AAAC;AAAC,IAAO,eAAQ;",
"names": []
}

441
node_modules/.vite/deps/react-toastify.js generated vendored Normal file

File diff suppressed because one or more lines are too long

7
node_modules/.vite/deps/react-toastify.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

1655
node_modules/.vite/deps/recharts.js generated vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

21
node_modules/react-toastify/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Fadi Khadra
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

117
node_modules/react-toastify/README.md generated vendored Normal file
View File

@@ -0,0 +1,117 @@
# React-Toastify
[![Financial Contributors on Open Collective](https://opencollective.com/react-toastify/all/badge.svg?label=financial+contributors)](https://opencollective.com/react-toastify) ![React-toastify CI](https://github.com/fkhadra/react-toastify/workflows/React-toastify%20CI/badge.svg)
![npm](https://img.shields.io/npm/dm/react-toastify.svg?label=%E2%8F%ACdownloads&style=for-the-badge)
![npm](https://img.shields.io/npm/v/react-toastify.svg?style=for-the-badge)
![NPM](https://img.shields.io/npm/l/react-toastify.svg?label=%F0%9F%93%9Clicense&style=for-the-badge)
![Coveralls github](https://img.shields.io/coveralls/github/fkhadra/react-toastify.svg?label=%E2%9B%B1coverage&style=for-the-badge)
![React toastify](https://user-images.githubusercontent.com/5574267/130804494-a9d2d69c-f170-4576-b2e1-0bb7f13dd92d.gif "React toastify")
![stacked](https://github.com/fkhadra/react-toastify/assets/5574267/975c7c01-b95e-43cf-9100-256fa8ef2760)
![custom-style](https://github.com/user-attachments/assets/311672f7-f98a-46f3-a2ab-a9d1a05186a7)
🎉 React-Toastify allows you to add notifications to your app with ease.
## Installation
```
$ npm install --save react-toastify
$ yarn add react-toastify
```
```jsx
import React from 'react';
import { ToastContainer, toast } from 'react-toastify';
function App(){
const notify = () => toast("Wow so easy!");
return (
<div>
<button onClick={notify}>Notify!</button>
<ToastContainer />
</div>
);
}
```
## Documentation
Check the [documentation](https://fkhadra.github.io/react-toastify/introduction) to get you started!
## Features
- Easy to set up for real, you can make it work in less than 10sec!
- Super easy to customize
- RTL support
- Swipe to close 👌
- Can choose swipe direction
- Super easy to use an animation of your choice. Works well with animate.css for example
- Can display a react component inside the toast!
- Has ```onOpen``` and ```onClose``` hooks. Both can access the props passed to the react component rendered inside the toast
- Can remove a toast programmatically
- Define behavior per toast
- Pause toast when the window loses focus 👁
- Fancy progress bar to display the remaining time
- Possibility to update a toast
- You can control the progress bar a la `nprogress` 😲
- You can limit the number of toast displayed at the same time
- Dark mode 🌒
- Pause timer programmaticaly
- Stacked notifications!
- And much more !
## Demo
[A demo is worth a thousand words](https://fkhadra.github.io/react-toastify/introduction)
## Contribute
Show your ❤️ and support by giving a ⭐. Any suggestions are welcome! Take a look at the contributing guide.
You can also find me on [reactiflux](https://www.reactiflux.com/). My pseudo is Fadi.
## Contributors
### Code Contributors
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
<a href="https://github.com/fkhadra/react-toastify/graphs/contributors"><img src="https://opencollective.com/react-toastify/contributors.svg?width=890&button=false" /></a>
### Financial Contributors
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/react-toastify/contribute)]
#### Individuals
<a href="https://opencollective.com/react-toastify"><img src="https://opencollective.com/react-toastify/individuals.svg?width=890"></a>
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/react-toastify/contribute)]
<a href="https://opencollective.com/react-toastify/organization/0/website"><img src="https://opencollective.com/react-toastify/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/1/website"><img src="https://opencollective.com/react-toastify/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/2/website"><img src="https://opencollective.com/react-toastify/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/3/website"><img src="https://opencollective.com/react-toastify/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/4/website"><img src="https://opencollective.com/react-toastify/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/5/website"><img src="https://opencollective.com/react-toastify/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/6/website"><img src="https://opencollective.com/react-toastify/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/7/website"><img src="https://opencollective.com/react-toastify/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/8/website"><img src="https://opencollective.com/react-toastify/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/9/website"><img src="https://opencollective.com/react-toastify/organization/9/avatar.svg"></a>
## Release Notes
You can find the release note for the latest release [here](https://github.com/fkhadra/react-toastify/releases/latest)
You can browse them all [here](https://github.com/fkhadra/react-toastify/releases)
## License
Licensed under MIT

View File

@@ -0,0 +1,161 @@
import { ToastItem, Id } from 'react-toastify';
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
interface NotificationCenterItem<Data = {}> extends Optional<ToastItem<Data>, 'content' | 'data' | 'status'> {
read: boolean;
createdAt: number;
}
type SortFn<Data> = (l: NotificationCenterItem<Data>, r: NotificationCenterItem<Data>) => number;
type FilterFn<Data = {}> = (item: NotificationCenterItem<Data>) => boolean;
interface UseNotificationCenterParams<Data = {}> {
/**
* initial data to rehydrate the notification center
*/
data?: NotificationCenterItem<Data>[];
/**
* By default, the notifications are sorted from the newest to the oldest using
* the `createdAt` field. Use this to provide your own sort function
*
* Usage:
* ```
* // old notifications first
* useNotificationCenter({
* sort: ((l, r) => l.createdAt - r.createdAt)
* })
* ```
*/
sort?: SortFn<Data>;
/**
* Keep the toast that meets the condition specified in the callback function.
*
* Usage:
* ```
* // keep only the toasts when hidden is set to false
* useNotificationCenter({
* filter: item => item.data.hidden === false
* })
* ```
*/
filter?: FilterFn<Data>;
}
interface UseNotificationCenter<Data> {
/**
* Contains all the notifications
*/
notifications: NotificationCenterItem<Data>[];
/**
* Clear all notifications
*/
clear(): void;
/**
* Mark all notification as read
*/
markAllAsRead(): void;
/**
* Mark all notification as read or not.
*
* Usage:
* ```
* markAllAsRead(false) // mark all notification as not read
*
* markAllAsRead(true) // same as calling markAllAsRead()
* ```
*/
markAllAsRead(read?: boolean): void;
/**
* Mark one or more notifications as read.
*
* Usage:
* ```
* markAsRead("anId")
* markAsRead(["a","list", "of", "id"])
* ```
*/
markAsRead(id: Id | Id[]): void;
/**
* Mark one or more notifications as read.The second parameter let you mark the notification as read or not.
*
* Usage:
* ```
* markAsRead("anId", false)
* markAsRead(["a","list", "of", "id"], false)
*
* markAsRead("anId", true) // same as markAsRead("anId")
* ```
*/
markAsRead(id: Id | Id[], read?: boolean): void;
/**
* Remove one or more notifications
*
* Usage:
* ```
* remove("anId")
* remove(["a","list", "of", "id"])
* ```
*/
remove(id: Id | Id[]): void;
/**
* Push a notification to the notification center.
* Returns null when an item with the given id already exists
*
* Usage:
* ```
* const id = add({id: "id", content: "test", data: { foo: "hello" } })
*
* // Return the id of the notification, generate one if none provided
* const id = add({ data: {title: "a title", text: "some text"} })
* ```
*/
add(item: Partial<NotificationCenterItem<Data>>): Id | null;
/**
* Update the notification that match the id
* Returns null when no matching notification found
*
* Usage:
* ```
* const id = update("anId", {content: "test", data: { foo: "hello" } })
*
* // It's also possible to update the id
* const id = update("anId"m { id:"anotherOne", data: {title: "a title", text: "some text"} })
* ```
*/
update(id: Id, item: Partial<NotificationCenterItem<Data>>): Id | null;
/**
* Retrieve one or more notifications
*
* Usage:
* ```
* find("anId")
* find(["a","list", "of", "id"])
* ```
*/
find(id: Id): NotificationCenterItem<Data> | undefined;
/**
* Retrieve one or more notifications
*
* Usage:
* ```
* find("anId")
* find(["a","list", "of", "id"])
* ```
*/
find(id: Id[]): NotificationCenterItem<Data>[] | undefined;
/**
* Retrieve the count for unread notifications
*/
unreadCount: number;
/**
* Sort notifications using the newly provided function
*
* Usage:
* ```
* // old notifications first
* sort((l, r) => l.createdAt - r.createdAt)
* ```
*/
sort(sort: SortFn<Data>): void;
}
declare function useNotificationCenter<Data = {}>(params?: UseNotificationCenterParams<Data>): UseNotificationCenter<Data>;
declare function decorate<Data>(item: NotificationCenterItem<Data> | Partial<NotificationCenterItem<Data>>): NotificationCenterItem<Data>;
export { type FilterFn, type NotificationCenterItem, type SortFn, type UseNotificationCenter, type UseNotificationCenterParams, decorate, useNotificationCenter };

View File

@@ -0,0 +1,161 @@
import { ToastItem, Id } from 'react-toastify';
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
interface NotificationCenterItem<Data = {}> extends Optional<ToastItem<Data>, 'content' | 'data' | 'status'> {
read: boolean;
createdAt: number;
}
type SortFn<Data> = (l: NotificationCenterItem<Data>, r: NotificationCenterItem<Data>) => number;
type FilterFn<Data = {}> = (item: NotificationCenterItem<Data>) => boolean;
interface UseNotificationCenterParams<Data = {}> {
/**
* initial data to rehydrate the notification center
*/
data?: NotificationCenterItem<Data>[];
/**
* By default, the notifications are sorted from the newest to the oldest using
* the `createdAt` field. Use this to provide your own sort function
*
* Usage:
* ```
* // old notifications first
* useNotificationCenter({
* sort: ((l, r) => l.createdAt - r.createdAt)
* })
* ```
*/
sort?: SortFn<Data>;
/**
* Keep the toast that meets the condition specified in the callback function.
*
* Usage:
* ```
* // keep only the toasts when hidden is set to false
* useNotificationCenter({
* filter: item => item.data.hidden === false
* })
* ```
*/
filter?: FilterFn<Data>;
}
interface UseNotificationCenter<Data> {
/**
* Contains all the notifications
*/
notifications: NotificationCenterItem<Data>[];
/**
* Clear all notifications
*/
clear(): void;
/**
* Mark all notification as read
*/
markAllAsRead(): void;
/**
* Mark all notification as read or not.
*
* Usage:
* ```
* markAllAsRead(false) // mark all notification as not read
*
* markAllAsRead(true) // same as calling markAllAsRead()
* ```
*/
markAllAsRead(read?: boolean): void;
/**
* Mark one or more notifications as read.
*
* Usage:
* ```
* markAsRead("anId")
* markAsRead(["a","list", "of", "id"])
* ```
*/
markAsRead(id: Id | Id[]): void;
/**
* Mark one or more notifications as read.The second parameter let you mark the notification as read or not.
*
* Usage:
* ```
* markAsRead("anId", false)
* markAsRead(["a","list", "of", "id"], false)
*
* markAsRead("anId", true) // same as markAsRead("anId")
* ```
*/
markAsRead(id: Id | Id[], read?: boolean): void;
/**
* Remove one or more notifications
*
* Usage:
* ```
* remove("anId")
* remove(["a","list", "of", "id"])
* ```
*/
remove(id: Id | Id[]): void;
/**
* Push a notification to the notification center.
* Returns null when an item with the given id already exists
*
* Usage:
* ```
* const id = add({id: "id", content: "test", data: { foo: "hello" } })
*
* // Return the id of the notification, generate one if none provided
* const id = add({ data: {title: "a title", text: "some text"} })
* ```
*/
add(item: Partial<NotificationCenterItem<Data>>): Id | null;
/**
* Update the notification that match the id
* Returns null when no matching notification found
*
* Usage:
* ```
* const id = update("anId", {content: "test", data: { foo: "hello" } })
*
* // It's also possible to update the id
* const id = update("anId"m { id:"anotherOne", data: {title: "a title", text: "some text"} })
* ```
*/
update(id: Id, item: Partial<NotificationCenterItem<Data>>): Id | null;
/**
* Retrieve one or more notifications
*
* Usage:
* ```
* find("anId")
* find(["a","list", "of", "id"])
* ```
*/
find(id: Id): NotificationCenterItem<Data> | undefined;
/**
* Retrieve one or more notifications
*
* Usage:
* ```
* find("anId")
* find(["a","list", "of", "id"])
* ```
*/
find(id: Id[]): NotificationCenterItem<Data>[] | undefined;
/**
* Retrieve the count for unread notifications
*/
unreadCount: number;
/**
* Sort notifications using the newly provided function
*
* Usage:
* ```
* // old notifications first
* sort((l, r) => l.createdAt - r.createdAt)
* ```
*/
sort(sort: SortFn<Data>): void;
}
declare function useNotificationCenter<Data = {}>(params?: UseNotificationCenterParams<Data>): UseNotificationCenter<Data>;
declare function decorate<Data>(item: NotificationCenterItem<Data> | Partial<NotificationCenterItem<Data>>): NotificationCenterItem<Data>;
export { type FilterFn, type NotificationCenterItem, type SortFn, type UseNotificationCenter, type UseNotificationCenterParams, decorate, useNotificationCenter };

View File

@@ -0,0 +1,3 @@
"use client";
var u=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var A=(a,i)=>{for(var d in i)u(a,d,{get:i[d],enumerable:!0})},x=(a,i,d,c)=>{if(i&&typeof i=="object"||typeof i=="function")for(let o of C(i))!N.call(a,o)&&o!==d&&u(a,o,{get:()=>i[o],enumerable:!(c=m(i,o))||c.enumerable});return a};var p=a=>x(u({},"__esModule",{value:!0}),a);var y={};A(y,{decorate:()=>l,useNotificationCenter:()=>b});module.exports=p(y);var s=require("react"),I=require("react-toastify");function b(a={}){let i=(0,s.useRef)(a.sort||k),d=(0,s.useRef)(a.filter||null),[c,o]=(0,s.useState)(()=>a.data?d.current?a.data.filter(d.current).sort(i.current):[...a.data].sort(i.current):[]);return(0,s.useEffect)(()=>I.toast.onChange(t=>{if(t.status==="added"||t.status==="updated"){let e=l(t);if(d.current&&!d.current(e))return;o(r=>{let n=[],f=r.findIndex(D=>D.id===e.id);return f!==-1?(n=r.slice(),Object.assign(n[f],e,{createdAt:Date.now()})):r.length===0?n=[e]:n=[e,...r],n.sort(i.current)})}}),[]),{notifications:c,clear:()=>{o([])},markAllAsRead:(t=!0)=>{o(e=>e.map(r=>(r.read=t,r)))},markAsRead:(t,e=!0)=>{let r=n=>(n.id===t&&(n.read=e),n);Array.isArray(t)&&(r=n=>(t.includes(n.id)&&(n.read=e),n)),o(n=>n.map(r))},add:t=>{if(c.find(r=>r.id===t.id))return null;let e=l(t);return o(r=>[...r,e].sort(i.current)),e.id},update:(t,e)=>{let r=c.findIndex(n=>n.id===t);return r!==-1?(o(n=>{let f=[...n];return Object.assign(f[r],e,{createdAt:e.createdAt||Date.now()}),f.sort(i.current)}),e.id):null},remove:t=>{o(e=>e.filter(Array.isArray(t)?r=>!t.includes(r.id):r=>r.id!==t))},find:t=>Array.isArray(t)?c.filter(e=>t.includes(e.id)):c.find(e=>e.id===t),sort:t=>{i.current=t,o(e=>e.slice().sort(t))},get unreadCount(){return c.reduce((t,e)=>e.read?t:t+1,0)}}}function l(a){return a.id==null&&(a.id=Date.now().toString(36).substring(2,9)),a.createdAt||(a.createdAt=Date.now()),a.read==null&&(a.read=!1),a}function k(a,i){return i.createdAt-a.createdAt}0&&(module.exports={decorate,useNotificationCenter});
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
"use client";
import{useState as I,useEffect as D,useRef as f}from"react";import{toast as m}from"react-toastify";function w(n={}){let i=f(n.sort||C),s=f(n.filter||null),[d,o]=I(()=>n.data?s.current?n.data.filter(s.current).sort(i.current):[...n.data].sort(i.current):[]);return D(()=>m.onChange(t=>{if(t.status==="added"||t.status==="updated"){let e=u(t);if(s.current&&!s.current(e))return;o(a=>{let r=[],c=a.findIndex(l=>l.id===e.id);return c!==-1?(r=a.slice(),Object.assign(r[c],e,{createdAt:Date.now()})):a.length===0?r=[e]:r=[e,...a],r.sort(i.current)})}}),[]),{notifications:d,clear:()=>{o([])},markAllAsRead:(t=!0)=>{o(e=>e.map(a=>(a.read=t,a)))},markAsRead:(t,e=!0)=>{let a=r=>(r.id===t&&(r.read=e),r);Array.isArray(t)&&(a=r=>(t.includes(r.id)&&(r.read=e),r)),o(r=>r.map(a))},add:t=>{if(d.find(a=>a.id===t.id))return null;let e=u(t);return o(a=>[...a,e].sort(i.current)),e.id},update:(t,e)=>{let a=d.findIndex(r=>r.id===t);return a!==-1?(o(r=>{let c=[...r];return Object.assign(c[a],e,{createdAt:e.createdAt||Date.now()}),c.sort(i.current)}),e.id):null},remove:t=>{o(e=>e.filter(Array.isArray(t)?a=>!t.includes(a.id):a=>a.id!==t))},find:t=>Array.isArray(t)?d.filter(e=>t.includes(e.id)):d.find(e=>e.id===t),sort:t=>{i.current=t,o(e=>e.slice().sort(t))},get unreadCount(){return d.reduce((t,e)=>e.read?t:t+1,0)}}}function u(n){return n.id==null&&(n.id=Date.now().toString(36).substring(2,9)),n.createdAt||(n.createdAt=Date.now()),n.read==null&&(n.read=!1),n}function C(n,i){return i.createdAt-n.createdAt}export{u as decorate,w as useNotificationCenter};
//# sourceMappingURL=index.mjs.map

File diff suppressed because one or more lines are too long

800
node_modules/react-toastify/dist/ReactToastify.css generated vendored Normal file
View File

@@ -0,0 +1,800 @@
:root {
--toastify-color-light: #fff;
--toastify-color-dark: #121212;
--toastify-color-info: #3498db;
--toastify-color-success: #07bc0c;
--toastify-color-warning: #f1c40f;
--toastify-color-error: hsl(6, 78%, 57%);
--toastify-color-transparent: rgba(255, 255, 255, 0.7);
--toastify-icon-color-info: var(--toastify-color-info);
--toastify-icon-color-success: var(--toastify-color-success);
--toastify-icon-color-warning: var(--toastify-color-warning);
--toastify-icon-color-error: var(--toastify-color-error);
--toastify-container-width: fit-content;
--toastify-toast-width: 320px;
--toastify-toast-offset: 16px;
--toastify-toast-top: max(var(--toastify-toast-offset), env(safe-area-inset-top));
--toastify-toast-right: max(var(--toastify-toast-offset), env(safe-area-inset-right));
--toastify-toast-left: max(var(--toastify-toast-offset), env(safe-area-inset-left));
--toastify-toast-bottom: max(var(--toastify-toast-offset), env(safe-area-inset-bottom));
--toastify-toast-background: #fff;
--toastify-toast-padding: 14px;
--toastify-toast-min-height: 64px;
--toastify-toast-max-height: 800px;
--toastify-toast-bd-radius: 6px;
--toastify-toast-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1);
--toastify-font-family: sans-serif;
--toastify-z-index: 9999;
--toastify-text-color-light: #757575;
--toastify-text-color-dark: #fff;
/* Used only for colored theme */
--toastify-text-color-info: #fff;
--toastify-text-color-success: #fff;
--toastify-text-color-warning: #fff;
--toastify-text-color-error: #fff;
--toastify-spinner-color: #616161;
--toastify-spinner-color-empty-area: #e0e0e0;
--toastify-color-progress-light: linear-gradient(to right, #4cd964, #5ac8fa, #007aff, #34aadc, #5856d6, #ff2d55);
--toastify-color-progress-dark: #bb86fc;
--toastify-color-progress-info: var(--toastify-color-info);
--toastify-color-progress-success: var(--toastify-color-success);
--toastify-color-progress-warning: var(--toastify-color-warning);
--toastify-color-progress-error: var(--toastify-color-error);
/* used to control the opacity of the progress trail */
--toastify-color-progress-bgo: 0.2;
}
.Toastify__toast-container {
z-index: var(--toastify-z-index);
-webkit-transform: translate3d(0, 0, var(--toastify-z-index));
position: fixed;
width: var(--toastify-container-width);
box-sizing: border-box;
color: #fff;
display: flex;
flex-direction: column;
}
.Toastify__toast-container--top-left {
top: var(--toastify-toast-top);
left: var(--toastify-toast-left);
}
.Toastify__toast-container--top-center {
top: var(--toastify-toast-top);
left: 50%;
transform: translateX(-50%);
align-items: center;
}
.Toastify__toast-container--top-right {
top: var(--toastify-toast-top);
right: var(--toastify-toast-right);
align-items: end;
}
.Toastify__toast-container--bottom-left {
bottom: var(--toastify-toast-bottom);
left: var(--toastify-toast-left);
}
.Toastify__toast-container--bottom-center {
bottom: var(--toastify-toast-bottom);
left: 50%;
transform: translateX(-50%);
align-items: center;
}
.Toastify__toast-container--bottom-right {
bottom: var(--toastify-toast-bottom);
right: var(--toastify-toast-right);
align-items: end;
}
.Toastify__toast {
--y: 0;
position: relative;
touch-action: none;
width: var(--toastify-toast-width);
min-height: var(--toastify-toast-min-height);
box-sizing: border-box;
margin-bottom: 1rem;
padding: var(--toastify-toast-padding);
border-radius: var(--toastify-toast-bd-radius);
box-shadow: var(--toastify-toast-shadow);
max-height: var(--toastify-toast-max-height);
font-family: var(--toastify-font-family);
/* webkit only issue #791 */
z-index: 0;
/* inner swag */
display: flex;
flex: 1 auto;
align-items: center;
word-break: break-word;
}
@media only screen and (max-width: 480px) {
.Toastify__toast-container {
width: 100vw;
left: env(safe-area-inset-left);
margin: 0;
}
.Toastify__toast-container--top-left,
.Toastify__toast-container--top-center,
.Toastify__toast-container--top-right {
top: env(safe-area-inset-top);
transform: translateX(0);
}
.Toastify__toast-container--bottom-left,
.Toastify__toast-container--bottom-center,
.Toastify__toast-container--bottom-right {
bottom: env(safe-area-inset-bottom);
transform: translateX(0);
}
.Toastify__toast-container--rtl {
right: env(safe-area-inset-right);
left: initial;
}
.Toastify__toast {
--toastify-toast-width: 100%;
margin-bottom: 0;
border-radius: 0;
}
}
.Toastify__toast-container[data-stacked='true'] {
width: var(--toastify-toast-width);
}
.Toastify__toast--stacked {
position: absolute;
width: 100%;
transform: translate3d(0, var(--y), 0) scale(var(--s));
transition: transform 0.3s;
}
.Toastify__toast--stacked[data-collapsed] .Toastify__toast-body,
.Toastify__toast--stacked[data-collapsed] .Toastify__close-button {
transition: opacity 0.1s;
}
.Toastify__toast--stacked[data-collapsed='false'] {
overflow: visible;
}
.Toastify__toast--stacked[data-collapsed='true']:not(:last-child) > * {
opacity: 0;
}
.Toastify__toast--stacked:after {
content: '';
position: absolute;
left: 0;
right: 0;
height: calc(var(--g) * 1px);
bottom: 100%;
}
.Toastify__toast--stacked[data-pos='top'] {
top: 0;
}
.Toastify__toast--stacked[data-pos='bot'] {
bottom: 0;
}
.Toastify__toast--stacked[data-pos='bot'].Toastify__toast--stacked:before {
transform-origin: top;
}
.Toastify__toast--stacked[data-pos='top'].Toastify__toast--stacked:before {
transform-origin: bottom;
}
.Toastify__toast--stacked:before {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 100%;
transform: scaleY(3);
z-index: -1;
}
.Toastify__toast--rtl {
direction: rtl;
}
.Toastify__toast--close-on-click {
cursor: pointer;
}
.Toastify__toast-icon {
margin-inline-end: 10px;
width: 22px;
flex-shrink: 0;
display: flex;
}
.Toastify--animate {
animation-fill-mode: both;
animation-duration: 0.5s;
}
.Toastify--animate-icon {
animation-fill-mode: both;
animation-duration: 0.3s;
}
.Toastify__toast-theme--dark {
background: var(--toastify-color-dark);
color: var(--toastify-text-color-dark);
}
.Toastify__toast-theme--light {
background: var(--toastify-color-light);
color: var(--toastify-text-color-light);
}
.Toastify__toast-theme--colored.Toastify__toast--default {
background: var(--toastify-color-light);
color: var(--toastify-text-color-light);
}
.Toastify__toast-theme--colored.Toastify__toast--info {
color: var(--toastify-text-color-info);
background: var(--toastify-color-info);
}
.Toastify__toast-theme--colored.Toastify__toast--success {
color: var(--toastify-text-color-success);
background: var(--toastify-color-success);
}
.Toastify__toast-theme--colored.Toastify__toast--warning {
color: var(--toastify-text-color-warning);
background: var(--toastify-color-warning);
}
.Toastify__toast-theme--colored.Toastify__toast--error {
color: var(--toastify-text-color-error);
background: var(--toastify-color-error);
}
.Toastify__progress-bar-theme--light {
background: var(--toastify-color-progress-light);
}
.Toastify__progress-bar-theme--dark {
background: var(--toastify-color-progress-dark);
}
.Toastify__progress-bar--info {
background: var(--toastify-color-progress-info);
}
.Toastify__progress-bar--success {
background: var(--toastify-color-progress-success);
}
.Toastify__progress-bar--warning {
background: var(--toastify-color-progress-warning);
}
.Toastify__progress-bar--error {
background: var(--toastify-color-progress-error);
}
.Toastify__progress-bar-theme--colored.Toastify__progress-bar--info,
.Toastify__progress-bar-theme--colored.Toastify__progress-bar--success,
.Toastify__progress-bar-theme--colored.Toastify__progress-bar--warning,
.Toastify__progress-bar-theme--colored.Toastify__progress-bar--error {
background: var(--toastify-color-transparent);
}
.Toastify__close-button {
color: #fff;
position: absolute;
top: 6px;
right: 6px;
background: transparent;
outline: none;
border: none;
padding: 0;
cursor: pointer;
opacity: 0.7;
transition: 0.3s ease;
z-index: 1;
}
.Toastify__toast--rtl .Toastify__close-button {
left: 6px;
right: unset;
}
.Toastify__close-button--light {
color: #000;
opacity: 0.3;
}
.Toastify__close-button > svg {
fill: currentColor;
height: 16px;
width: 14px;
}
.Toastify__close-button:hover,
.Toastify__close-button:focus {
opacity: 1;
}
@keyframes Toastify__trackProgress {
0% {
transform: scaleX(1);
}
100% {
transform: scaleX(0);
}
}
.Toastify__progress-bar {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
opacity: 0.7;
transform-origin: left;
}
.Toastify__progress-bar--animated {
animation: Toastify__trackProgress linear 1 forwards;
}
.Toastify__progress-bar--controlled {
transition: transform 0.2s;
}
.Toastify__progress-bar--rtl {
right: 0;
left: initial;
transform-origin: right;
border-bottom-left-radius: initial;
}
.Toastify__progress-bar--wrp {
position: absolute;
overflow: hidden;
bottom: 0;
left: 0;
width: 100%;
height: 5px;
border-bottom-left-radius: var(--toastify-toast-bd-radius);
border-bottom-right-radius: var(--toastify-toast-bd-radius);
}
.Toastify__progress-bar--wrp[data-hidden='true'] {
opacity: 0;
}
.Toastify__progress-bar--bg {
opacity: var(--toastify-color-progress-bgo);
width: 100%;
height: 100%;
}
.Toastify__spinner {
width: 20px;
height: 20px;
box-sizing: border-box;
border: 2px solid;
border-radius: 100%;
border-color: var(--toastify-spinner-color-empty-area);
border-right-color: var(--toastify-spinner-color);
animation: Toastify__spin 0.65s linear infinite;
}
@keyframes Toastify__bounceInRight {
from,
60%,
75%,
90%,
to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
from {
opacity: 0;
transform: translate3d(3000px, 0, 0);
}
60% {
opacity: 1;
transform: translate3d(-25px, 0, 0);
}
75% {
transform: translate3d(10px, 0, 0);
}
90% {
transform: translate3d(-5px, 0, 0);
}
to {
transform: none;
}
}
@keyframes Toastify__bounceOutRight {
20% {
opacity: 1;
transform: translate3d(-20px, var(--y), 0);
}
to {
opacity: 0;
transform: translate3d(2000px, var(--y), 0);
}
}
@keyframes Toastify__bounceInLeft {
from,
60%,
75%,
90%,
to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
0% {
opacity: 0;
transform: translate3d(-3000px, 0, 0);
}
60% {
opacity: 1;
transform: translate3d(25px, 0, 0);
}
75% {
transform: translate3d(-10px, 0, 0);
}
90% {
transform: translate3d(5px, 0, 0);
}
to {
transform: none;
}
}
@keyframes Toastify__bounceOutLeft {
20% {
opacity: 1;
transform: translate3d(20px, var(--y), 0);
}
to {
opacity: 0;
transform: translate3d(-2000px, var(--y), 0);
}
}
@keyframes Toastify__bounceInUp {
from,
60%,
75%,
90%,
to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
from {
opacity: 0;
transform: translate3d(0, 3000px, 0);
}
60% {
opacity: 1;
transform: translate3d(0, -20px, 0);
}
75% {
transform: translate3d(0, 10px, 0);
}
90% {
transform: translate3d(0, -5px, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes Toastify__bounceOutUp {
20% {
transform: translate3d(0, calc(var(--y) - 10px), 0);
}
40%,
45% {
opacity: 1;
transform: translate3d(0, calc(var(--y) + 20px), 0);
}
to {
opacity: 0;
transform: translate3d(0, -2000px, 0);
}
}
@keyframes Toastify__bounceInDown {
from,
60%,
75%,
90%,
to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
0% {
opacity: 0;
transform: translate3d(0, -3000px, 0);
}
60% {
opacity: 1;
transform: translate3d(0, 25px, 0);
}
75% {
transform: translate3d(0, -10px, 0);
}
90% {
transform: translate3d(0, 5px, 0);
}
to {
transform: none;
}
}
@keyframes Toastify__bounceOutDown {
20% {
transform: translate3d(0, calc(var(--y) - 10px), 0);
}
40%,
45% {
opacity: 1;
transform: translate3d(0, calc(var(--y) + 20px), 0);
}
to {
opacity: 0;
transform: translate3d(0, 2000px, 0);
}
}
.Toastify__bounce-enter--top-left,
.Toastify__bounce-enter--bottom-left {
animation-name: Toastify__bounceInLeft;
}
.Toastify__bounce-enter--top-right,
.Toastify__bounce-enter--bottom-right {
animation-name: Toastify__bounceInRight;
}
.Toastify__bounce-enter--top-center {
animation-name: Toastify__bounceInDown;
}
.Toastify__bounce-enter--bottom-center {
animation-name: Toastify__bounceInUp;
}
.Toastify__bounce-exit--top-left,
.Toastify__bounce-exit--bottom-left {
animation-name: Toastify__bounceOutLeft;
}
.Toastify__bounce-exit--top-right,
.Toastify__bounce-exit--bottom-right {
animation-name: Toastify__bounceOutRight;
}
.Toastify__bounce-exit--top-center {
animation-name: Toastify__bounceOutUp;
}
.Toastify__bounce-exit--bottom-center {
animation-name: Toastify__bounceOutDown;
}
@keyframes Toastify__zoomIn {
from {
opacity: 0;
transform: scale3d(0.3, 0.3, 0.3);
}
50% {
opacity: 1;
}
}
@keyframes Toastify__zoomOut {
from {
opacity: 1;
}
50% {
opacity: 0;
transform: translate3d(0, var(--y), 0) scale3d(0.3, 0.3, 0.3);
}
to {
opacity: 0;
}
}
.Toastify__zoom-enter {
animation-name: Toastify__zoomIn;
}
.Toastify__zoom-exit {
animation-name: Toastify__zoomOut;
}
@keyframes Toastify__flipIn {
from {
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
animation-timing-function: ease-in;
opacity: 0;
}
40% {
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
animation-timing-function: ease-in;
}
60% {
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}
80% {
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
to {
transform: perspective(400px);
}
}
@keyframes Toastify__flipOut {
from {
transform: translate3d(0, var(--y), 0) perspective(400px);
}
30% {
transform: translate3d(0, var(--y), 0) perspective(400px) rotate3d(1, 0, 0, -20deg);
opacity: 1;
}
to {
transform: translate3d(0, var(--y), 0) perspective(400px) rotate3d(1, 0, 0, 90deg);
opacity: 0;
}
}
.Toastify__flip-enter {
animation-name: Toastify__flipIn;
}
.Toastify__flip-exit {
animation-name: Toastify__flipOut;
}
@keyframes Toastify__slideInRight {
from {
transform: translate3d(110%, 0, 0);
visibility: visible;
}
to {
transform: translate3d(0, var(--y), 0);
}
}
@keyframes Toastify__slideInLeft {
from {
transform: translate3d(-110%, 0, 0);
visibility: visible;
}
to {
transform: translate3d(0, var(--y), 0);
}
}
@keyframes Toastify__slideInUp {
from {
transform: translate3d(0, 110%, 0);
visibility: visible;
}
to {
transform: translate3d(0, var(--y), 0);
}
}
@keyframes Toastify__slideInDown {
from {
transform: translate3d(0, -110%, 0);
visibility: visible;
}
to {
transform: translate3d(0, var(--y), 0);
}
}
@keyframes Toastify__slideOutRight {
from {
transform: translate3d(0, var(--y), 0);
}
to {
visibility: hidden;
transform: translate3d(110%, var(--y), 0);
}
}
@keyframes Toastify__slideOutLeft {
from {
transform: translate3d(0, var(--y), 0);
}
to {
visibility: hidden;
transform: translate3d(-110%, var(--y), 0);
}
}
@keyframes Toastify__slideOutDown {
from {
transform: translate3d(0, var(--y), 0);
}
to {
visibility: hidden;
transform: translate3d(0, 500px, 0);
}
}
@keyframes Toastify__slideOutUp {
from {
transform: translate3d(0, var(--y), 0);
}
to {
visibility: hidden;
transform: translate3d(0, -500px, 0);
}
}
.Toastify__slide-enter--top-left,
.Toastify__slide-enter--bottom-left {
animation-name: Toastify__slideInLeft;
}
.Toastify__slide-enter--top-right,
.Toastify__slide-enter--bottom-right {
animation-name: Toastify__slideInRight;
}
.Toastify__slide-enter--top-center {
animation-name: Toastify__slideInDown;
}
.Toastify__slide-enter--bottom-center {
animation-name: Toastify__slideInUp;
}
.Toastify__slide-exit--top-left,
.Toastify__slide-exit--bottom-left {
animation-name: Toastify__slideOutLeft;
animation-timing-function: ease-in;
animation-duration: 0.3s;
}
.Toastify__slide-exit--top-right,
.Toastify__slide-exit--bottom-right {
animation-name: Toastify__slideOutRight;
animation-timing-function: ease-in;
animation-duration: 0.3s;
}
.Toastify__slide-exit--top-center {
animation-name: Toastify__slideOutUp;
animation-timing-function: ease-in;
animation-duration: 0.3s;
}
.Toastify__slide-exit--bottom-center {
animation-name: Toastify__slideOutDown;
animation-timing-function: ease-in;
animation-duration: 0.3s;
}
@keyframes Toastify__spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

410
node_modules/react-toastify/dist/index.d.mts generated vendored Normal file
View File

@@ -0,0 +1,410 @@
import * as React from 'react';
import React__default, { HTMLAttributes } from 'react';
interface CloseButtonProps {
closeToast: CloseToastFunc;
type: TypeOptions;
ariaLabel?: string;
theme: Theme;
}
declare function CloseButton({ closeToast, theme, ariaLabel }: CloseButtonProps): React__default.JSX.Element;
declare function ToastContainer(props: ToastContainerProps): React__default.JSX.Element;
declare const Bounce: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Slide: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Zoom: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Flip: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
/**
* Used when providing custom icon
*/
interface IconProps {
theme: Theme;
type: TypeOptions;
isLoading?: boolean;
}
type BuiltInIconProps = React__default.SVGProps<SVGSVGElement> & IconProps;
declare function Warning(props: BuiltInIconProps): React__default.JSX.Element;
declare function Info(props: BuiltInIconProps): React__default.JSX.Element;
declare function Success(props: BuiltInIconProps): React__default.JSX.Element;
declare function Error(props: BuiltInIconProps): React__default.JSX.Element;
declare function Spinner(): React__default.JSX.Element;
declare const Icons: {
info: typeof Info;
warning: typeof Warning;
success: typeof Success;
error: typeof Error;
spinner: typeof Spinner;
};
declare function isToastActive(id: Id, containerId?: Id): boolean;
declare const clearWaitingQueue: (p?: ClearWaitingQueueParams) => void;
type Nullable<T> = {
[P in keyof T]: T[P] | null;
};
type TypeOptions = 'info' | 'success' | 'warning' | 'error' | 'default';
type Theme = 'light' | 'dark' | 'colored' | (string & {});
type ToastPosition = 'top-right' | 'top-center' | 'top-left' | 'bottom-right' | 'bottom-center' | 'bottom-left';
type CloseToastFunc = ((reason?: boolean | string) => void) & ((e: React__default.MouseEvent) => void);
interface ToastContentProps<Data = unknown> {
closeToast: CloseToastFunc;
toastProps: ToastProps;
isPaused: boolean;
data: Data;
}
type ToastContent<T = unknown> = React__default.ReactNode | ((props: ToastContentProps<T>) => React__default.ReactNode);
type ToastIcon = false | ((props: IconProps) => React__default.ReactNode) | React__default.ReactElement<IconProps>;
type Id = number | string;
type ToastTransition = React__default.FC<ToastTransitionProps> | React__default.ComponentClass<ToastTransitionProps>;
/**
* ClassName for the elements - can take a function to build a classname or a raw string that is cx'ed to defaults
*/
type ToastClassName = ((context?: {
type?: TypeOptions;
defaultClassName?: string;
position?: ToastPosition;
rtl?: boolean;
}) => string) | string;
interface ClearWaitingQueueParams {
containerId?: Id;
}
type DraggableDirection = 'x' | 'y';
interface CommonOptions {
/**
* Pause the timer when the mouse hover the toast.
* `Default: true`
*/
pauseOnHover?: boolean;
/**
* Pause the toast when the window loses focus.
* `Default: true`
*/
pauseOnFocusLoss?: boolean;
/**
* Remove the toast when clicked.
* `Default: false`
*/
closeOnClick?: boolean;
/**
* Set the delay in ms to close the toast automatically.
* Use `false` to prevent the toast from closing.
* `Default: 5000`
*/
autoClose?: number | false;
/**
* Set the default position to use.
* `One of: 'top-right', 'top-center', 'top-left', 'bottom-right', 'bottom-center', 'bottom-left'`
* `Default: 'top-right'`
*/
position?: ToastPosition;
/**
* Pass a custom close button.
* To remove the close button pass `false`
*/
closeButton?: boolean | ((props: CloseButtonProps) => React__default.ReactNode) | React__default.ReactElement<CloseButtonProps>;
/**
* An optional css class to set for the progress bar.
*/
progressClassName?: ToastClassName;
/**
* Hide or show the progress bar.
* `Default: false`
*/
hideProgressBar?: boolean;
/**
* Pass a custom transition see https://fkhadra.github.io/react-toastify/custom-animation/
*/
transition?: ToastTransition;
/**
* Allow toast to be draggable
* `Default: 'touch'`
*/
draggable?: boolean | 'mouse' | 'touch';
/**
* The percentage of the toast's width it takes for a drag to dismiss a toast
* `Default: 80`
*/
draggablePercent?: number;
/**
* Specify in which direction should you swipe to dismiss the toast
* `Default: "x"`
*/
draggableDirection?: DraggableDirection;
/**
* Define the ARIA role for the toast
* `Default: alert`
* https://www.w3.org/WAI/PF/aria/roles
*/
role?: string;
/**
* Set id to handle multiple container
*/
containerId?: Id;
/**
* Fired when clicking inside toaster
*/
onClick?: (event: React__default.MouseEvent) => void;
/**
* Support right to left display.
* `Default: false`
*/
rtl?: boolean;
/**
* Used to display a custom icon. Set it to `false` to prevent
* the icons from being displayed
*/
icon?: ToastIcon;
/**
* Theme to use.
* `One of: 'light', 'dark', 'colored'`
* `Default: 'light'`
*/
theme?: Theme;
/**
* When set to `true` the built-in progress bar won't be rendered at all. Autoclose delay won't have any effect as well
* This is only used when you want to replace the progress bar with your own.
*
* See https://stackblitz.com/edit/react-toastify-custom-progress-bar?file=src%2FApp.tsx for an example.
*/
customProgressBar?: boolean;
}
interface ToastOptions<Data = unknown> extends CommonOptions {
/**
* An optional css class to set.
*/
className?: ToastClassName;
/**
* Called when toast is mounted.
*/
onOpen?: () => void;
/**
* Called when toast is unmounted.
* The callback first argument is the closure reason.
* It is "true" when the notification is closed by a user action like clicking on the close button.
*/
onClose?: (reason?: boolean | string) => void;
/**
* An optional inline style to apply.
*/
style?: React__default.CSSProperties;
/**
* Set the toast type.
* `One of: 'info', 'success', 'warning', 'error', 'default'`
*/
type?: TypeOptions;
/**
* Set a custom `toastId`
*/
toastId?: Id;
/**
* Used during update
*/
updateId?: Id;
/**
* Set the percentage for the controlled progress bar. `Value must be between 0 and 1.`
*/
progress?: number;
/**
* Let you provide any data, useful when you are using your own component
*/
data?: Data;
/**
* Let you specify the aria-label
*/
ariaLabel?: string;
/**
* Add a delay in ms before the toast appear.
*/
delay?: number;
isLoading?: boolean;
}
interface UpdateOptions<T = unknown> extends Nullable<ToastOptions<T>> {
/**
* Used to update a toast.
* Pass any valid ReactNode(string, number, component)
*/
render?: ToastContent<T>;
}
interface ToastContainerProps extends CommonOptions, Pick<HTMLAttributes<HTMLElement>, 'aria-label'> {
/**
* An optional css class to set.
*/
className?: ToastClassName;
/**
* Will stack the toast with the newest on the top.
*/
stacked?: boolean;
/**
* Whether or not to display the newest toast on top.
* `Default: false`
*/
newestOnTop?: boolean;
/**
* An optional inline style to apply.
*/
style?: React__default.CSSProperties;
/**
* An optional inline style to apply for the toast.
*/
toastStyle?: React__default.CSSProperties;
/**
* An optional css class for the toast.
*/
toastClassName?: ToastClassName;
/**
* Limit the number of toast displayed at the same time
*/
limit?: number;
/**
* Shortcut to focus the first notification with the keyboard
* `default: Alt+t`
*
* ```
* // focus when user presses ⌘ + F
* const matchShortcut = (e: KeyboardEvent) => e.metaKey && e.key === 'f'
* ```
*/
hotKeys?: (e: KeyboardEvent) => boolean;
}
interface ToastTransitionProps {
isIn: boolean;
done: () => void;
position: ToastPosition | string;
preventExitTransition: boolean;
nodeRef: React__default.RefObject<HTMLElement>;
children?: React__default.ReactNode;
playToast(): void;
}
/**
* @INTERNAL
*/
interface ToastProps extends ToastOptions {
isIn: boolean;
staleId?: Id;
toastId: Id;
key: Id;
transition: ToastTransition;
closeToast: CloseToastFunc;
position: ToastPosition;
children?: ToastContent;
draggablePercent: number;
draggableDirection?: DraggableDirection;
progressClassName?: ToastClassName;
className?: ToastClassName;
deleteToast: () => void;
theme: Theme;
type: TypeOptions;
collapseAll: () => void;
stacked?: boolean;
}
type ToastItemStatus = 'added' | 'removed' | 'updated';
interface ToastItem<Data = {}> {
content: ToastContent<Data>;
id: Id;
theme?: Theme;
type?: TypeOptions;
isLoading?: boolean;
containerId?: Id;
data: Data;
icon?: ToastIcon;
status: ToastItemStatus;
reason?: boolean | string;
}
type OnChangeCallback = (toast: ToastItem) => void;
type IdOpts = {
id?: Id;
containerId?: Id;
};
type ClearWaitingQueueFunc = typeof clearWaitingQueue;
declare const enum Default {
COLLAPSE_DURATION = 300,
DEBOUNCE_DURATION = 50,
CSS_NAMESPACE = "Toastify",
DRAGGABLE_PERCENT = 80,
CONTAINER_ID = 1
}
interface CSSTransitionProps {
/**
* Css class to apply when toast enter
*/
enter: string;
/**
* Css class to apply when toast leave
*/
exit: string;
/**
* Append current toast position to the classname.
* If multiple classes are provided, only the last one will get the position
* For instance `myclass--top-center`...
* `Default: false`
*/
appendPosition?: boolean;
/**
* Collapse toast smoothly when exit animation end
* `Default: true`
*/
collapse?: boolean;
/**
* Collapse transition duration
* `Default: 300`
*/
collapseDuration?: number;
}
/**
* Css animation that just work.
* You could use animate.css for instance
*
*
* ```
* cssTransition({
* enter: "animate__animated animate__bounceIn",
* exit: "animate__animated animate__bounceOut"
* })
* ```
*
*/
declare function cssTransition({ enter, exit, appendPosition, collapse, collapseDuration }: CSSTransitionProps): ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React__default.JSX.Element;
/**
* Used to collapse toast after exit animation
*/
declare function collapseToast(node: HTMLElement, done: () => void, duration?: Default): void;
declare function toast<TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>): Id;
declare namespace toast {
var loading: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var promise: typeof handlePromise;
var success: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var info: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var error: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var warning: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var warn: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var dark: (content: ToastContent, options?: ToastOptions) => Id;
var dismiss: {
(params: RemoveParams): void;
(params?: Id): void;
};
var clearWaitingQueue: (p?: ClearWaitingQueueParams) => void;
var isActive: typeof isToastActive;
var update: <TData = unknown>(toastId: Id, options?: UpdateOptions<TData>) => void;
var done: (id: Id) => void;
var onChange: (cb: OnChangeCallback) => () => void;
var play: (opts?: IdOpts) => void;
var pause: (opts?: IdOpts) => void;
}
interface ToastPromiseParams<TData = unknown, TError = unknown, TPending = unknown> {
pending?: string | UpdateOptions<TPending>;
success?: string | UpdateOptions<TData>;
error?: string | UpdateOptions<TError>;
}
declare function handlePromise<TData = unknown, TError = unknown, TPending = unknown>(promise: Promise<TData> | (() => Promise<TData>), { pending, error, success }: ToastPromiseParams<TData, TError, TPending>, options?: ToastOptions<TData>): Promise<TData>;
interface RemoveParams {
id?: Id;
containerId: Id;
}
export { Bounce, type ClearWaitingQueueFunc, type ClearWaitingQueueParams, CloseButton, type CloseButtonProps, type DraggableDirection, Flip, type IconProps, Icons, type Id, type OnChangeCallback, Slide, type Theme, type ToastClassName, ToastContainer, type ToastContainerProps, type ToastContent, type ToastContentProps, type ToastIcon, type ToastItem, type ToastOptions, type ToastPosition, type ToastPromiseParams, type ToastTransition, type ToastTransitionProps, type TypeOptions, type UpdateOptions, Zoom, collapseToast, cssTransition, toast };

410
node_modules/react-toastify/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,410 @@
import * as React from 'react';
import React__default, { HTMLAttributes } from 'react';
interface CloseButtonProps {
closeToast: CloseToastFunc;
type: TypeOptions;
ariaLabel?: string;
theme: Theme;
}
declare function CloseButton({ closeToast, theme, ariaLabel }: CloseButtonProps): React__default.JSX.Element;
declare function ToastContainer(props: ToastContainerProps): React__default.JSX.Element;
declare const Bounce: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Slide: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Zoom: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Flip: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
/**
* Used when providing custom icon
*/
interface IconProps {
theme: Theme;
type: TypeOptions;
isLoading?: boolean;
}
type BuiltInIconProps = React__default.SVGProps<SVGSVGElement> & IconProps;
declare function Warning(props: BuiltInIconProps): React__default.JSX.Element;
declare function Info(props: BuiltInIconProps): React__default.JSX.Element;
declare function Success(props: BuiltInIconProps): React__default.JSX.Element;
declare function Error(props: BuiltInIconProps): React__default.JSX.Element;
declare function Spinner(): React__default.JSX.Element;
declare const Icons: {
info: typeof Info;
warning: typeof Warning;
success: typeof Success;
error: typeof Error;
spinner: typeof Spinner;
};
declare function isToastActive(id: Id, containerId?: Id): boolean;
declare const clearWaitingQueue: (p?: ClearWaitingQueueParams) => void;
type Nullable<T> = {
[P in keyof T]: T[P] | null;
};
type TypeOptions = 'info' | 'success' | 'warning' | 'error' | 'default';
type Theme = 'light' | 'dark' | 'colored' | (string & {});
type ToastPosition = 'top-right' | 'top-center' | 'top-left' | 'bottom-right' | 'bottom-center' | 'bottom-left';
type CloseToastFunc = ((reason?: boolean | string) => void) & ((e: React__default.MouseEvent) => void);
interface ToastContentProps<Data = unknown> {
closeToast: CloseToastFunc;
toastProps: ToastProps;
isPaused: boolean;
data: Data;
}
type ToastContent<T = unknown> = React__default.ReactNode | ((props: ToastContentProps<T>) => React__default.ReactNode);
type ToastIcon = false | ((props: IconProps) => React__default.ReactNode) | React__default.ReactElement<IconProps>;
type Id = number | string;
type ToastTransition = React__default.FC<ToastTransitionProps> | React__default.ComponentClass<ToastTransitionProps>;
/**
* ClassName for the elements - can take a function to build a classname or a raw string that is cx'ed to defaults
*/
type ToastClassName = ((context?: {
type?: TypeOptions;
defaultClassName?: string;
position?: ToastPosition;
rtl?: boolean;
}) => string) | string;
interface ClearWaitingQueueParams {
containerId?: Id;
}
type DraggableDirection = 'x' | 'y';
interface CommonOptions {
/**
* Pause the timer when the mouse hover the toast.
* `Default: true`
*/
pauseOnHover?: boolean;
/**
* Pause the toast when the window loses focus.
* `Default: true`
*/
pauseOnFocusLoss?: boolean;
/**
* Remove the toast when clicked.
* `Default: false`
*/
closeOnClick?: boolean;
/**
* Set the delay in ms to close the toast automatically.
* Use `false` to prevent the toast from closing.
* `Default: 5000`
*/
autoClose?: number | false;
/**
* Set the default position to use.
* `One of: 'top-right', 'top-center', 'top-left', 'bottom-right', 'bottom-center', 'bottom-left'`
* `Default: 'top-right'`
*/
position?: ToastPosition;
/**
* Pass a custom close button.
* To remove the close button pass `false`
*/
closeButton?: boolean | ((props: CloseButtonProps) => React__default.ReactNode) | React__default.ReactElement<CloseButtonProps>;
/**
* An optional css class to set for the progress bar.
*/
progressClassName?: ToastClassName;
/**
* Hide or show the progress bar.
* `Default: false`
*/
hideProgressBar?: boolean;
/**
* Pass a custom transition see https://fkhadra.github.io/react-toastify/custom-animation/
*/
transition?: ToastTransition;
/**
* Allow toast to be draggable
* `Default: 'touch'`
*/
draggable?: boolean | 'mouse' | 'touch';
/**
* The percentage of the toast's width it takes for a drag to dismiss a toast
* `Default: 80`
*/
draggablePercent?: number;
/**
* Specify in which direction should you swipe to dismiss the toast
* `Default: "x"`
*/
draggableDirection?: DraggableDirection;
/**
* Define the ARIA role for the toast
* `Default: alert`
* https://www.w3.org/WAI/PF/aria/roles
*/
role?: string;
/**
* Set id to handle multiple container
*/
containerId?: Id;
/**
* Fired when clicking inside toaster
*/
onClick?: (event: React__default.MouseEvent) => void;
/**
* Support right to left display.
* `Default: false`
*/
rtl?: boolean;
/**
* Used to display a custom icon. Set it to `false` to prevent
* the icons from being displayed
*/
icon?: ToastIcon;
/**
* Theme to use.
* `One of: 'light', 'dark', 'colored'`
* `Default: 'light'`
*/
theme?: Theme;
/**
* When set to `true` the built-in progress bar won't be rendered at all. Autoclose delay won't have any effect as well
* This is only used when you want to replace the progress bar with your own.
*
* See https://stackblitz.com/edit/react-toastify-custom-progress-bar?file=src%2FApp.tsx for an example.
*/
customProgressBar?: boolean;
}
interface ToastOptions<Data = unknown> extends CommonOptions {
/**
* An optional css class to set.
*/
className?: ToastClassName;
/**
* Called when toast is mounted.
*/
onOpen?: () => void;
/**
* Called when toast is unmounted.
* The callback first argument is the closure reason.
* It is "true" when the notification is closed by a user action like clicking on the close button.
*/
onClose?: (reason?: boolean | string) => void;
/**
* An optional inline style to apply.
*/
style?: React__default.CSSProperties;
/**
* Set the toast type.
* `One of: 'info', 'success', 'warning', 'error', 'default'`
*/
type?: TypeOptions;
/**
* Set a custom `toastId`
*/
toastId?: Id;
/**
* Used during update
*/
updateId?: Id;
/**
* Set the percentage for the controlled progress bar. `Value must be between 0 and 1.`
*/
progress?: number;
/**
* Let you provide any data, useful when you are using your own component
*/
data?: Data;
/**
* Let you specify the aria-label
*/
ariaLabel?: string;
/**
* Add a delay in ms before the toast appear.
*/
delay?: number;
isLoading?: boolean;
}
interface UpdateOptions<T = unknown> extends Nullable<ToastOptions<T>> {
/**
* Used to update a toast.
* Pass any valid ReactNode(string, number, component)
*/
render?: ToastContent<T>;
}
interface ToastContainerProps extends CommonOptions, Pick<HTMLAttributes<HTMLElement>, 'aria-label'> {
/**
* An optional css class to set.
*/
className?: ToastClassName;
/**
* Will stack the toast with the newest on the top.
*/
stacked?: boolean;
/**
* Whether or not to display the newest toast on top.
* `Default: false`
*/
newestOnTop?: boolean;
/**
* An optional inline style to apply.
*/
style?: React__default.CSSProperties;
/**
* An optional inline style to apply for the toast.
*/
toastStyle?: React__default.CSSProperties;
/**
* An optional css class for the toast.
*/
toastClassName?: ToastClassName;
/**
* Limit the number of toast displayed at the same time
*/
limit?: number;
/**
* Shortcut to focus the first notification with the keyboard
* `default: Alt+t`
*
* ```
* // focus when user presses ⌘ + F
* const matchShortcut = (e: KeyboardEvent) => e.metaKey && e.key === 'f'
* ```
*/
hotKeys?: (e: KeyboardEvent) => boolean;
}
interface ToastTransitionProps {
isIn: boolean;
done: () => void;
position: ToastPosition | string;
preventExitTransition: boolean;
nodeRef: React__default.RefObject<HTMLElement>;
children?: React__default.ReactNode;
playToast(): void;
}
/**
* @INTERNAL
*/
interface ToastProps extends ToastOptions {
isIn: boolean;
staleId?: Id;
toastId: Id;
key: Id;
transition: ToastTransition;
closeToast: CloseToastFunc;
position: ToastPosition;
children?: ToastContent;
draggablePercent: number;
draggableDirection?: DraggableDirection;
progressClassName?: ToastClassName;
className?: ToastClassName;
deleteToast: () => void;
theme: Theme;
type: TypeOptions;
collapseAll: () => void;
stacked?: boolean;
}
type ToastItemStatus = 'added' | 'removed' | 'updated';
interface ToastItem<Data = {}> {
content: ToastContent<Data>;
id: Id;
theme?: Theme;
type?: TypeOptions;
isLoading?: boolean;
containerId?: Id;
data: Data;
icon?: ToastIcon;
status: ToastItemStatus;
reason?: boolean | string;
}
type OnChangeCallback = (toast: ToastItem) => void;
type IdOpts = {
id?: Id;
containerId?: Id;
};
type ClearWaitingQueueFunc = typeof clearWaitingQueue;
declare const enum Default {
COLLAPSE_DURATION = 300,
DEBOUNCE_DURATION = 50,
CSS_NAMESPACE = "Toastify",
DRAGGABLE_PERCENT = 80,
CONTAINER_ID = 1
}
interface CSSTransitionProps {
/**
* Css class to apply when toast enter
*/
enter: string;
/**
* Css class to apply when toast leave
*/
exit: string;
/**
* Append current toast position to the classname.
* If multiple classes are provided, only the last one will get the position
* For instance `myclass--top-center`...
* `Default: false`
*/
appendPosition?: boolean;
/**
* Collapse toast smoothly when exit animation end
* `Default: true`
*/
collapse?: boolean;
/**
* Collapse transition duration
* `Default: 300`
*/
collapseDuration?: number;
}
/**
* Css animation that just work.
* You could use animate.css for instance
*
*
* ```
* cssTransition({
* enter: "animate__animated animate__bounceIn",
* exit: "animate__animated animate__bounceOut"
* })
* ```
*
*/
declare function cssTransition({ enter, exit, appendPosition, collapse, collapseDuration }: CSSTransitionProps): ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React__default.JSX.Element;
/**
* Used to collapse toast after exit animation
*/
declare function collapseToast(node: HTMLElement, done: () => void, duration?: Default): void;
declare function toast<TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>): Id;
declare namespace toast {
var loading: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var promise: typeof handlePromise;
var success: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var info: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var error: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var warning: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var warn: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var dark: (content: ToastContent, options?: ToastOptions) => Id;
var dismiss: {
(params: RemoveParams): void;
(params?: Id): void;
};
var clearWaitingQueue: (p?: ClearWaitingQueueParams) => void;
var isActive: typeof isToastActive;
var update: <TData = unknown>(toastId: Id, options?: UpdateOptions<TData>) => void;
var done: (id: Id) => void;
var onChange: (cb: OnChangeCallback) => () => void;
var play: (opts?: IdOpts) => void;
var pause: (opts?: IdOpts) => void;
}
interface ToastPromiseParams<TData = unknown, TError = unknown, TPending = unknown> {
pending?: string | UpdateOptions<TPending>;
success?: string | UpdateOptions<TData>;
error?: string | UpdateOptions<TError>;
}
declare function handlePromise<TData = unknown, TError = unknown, TPending = unknown>(promise: Promise<TData> | (() => Promise<TData>), { pending, error, success }: ToastPromiseParams<TData, TError, TPending>, options?: ToastOptions<TData>): Promise<TData>;
interface RemoveParams {
id?: Id;
containerId: Id;
}
export { Bounce, type ClearWaitingQueueFunc, type ClearWaitingQueueParams, CloseButton, type CloseButtonProps, type DraggableDirection, Flip, type IconProps, Icons, type Id, type OnChangeCallback, Slide, type Theme, type ToastClassName, ToastContainer, type ToastContainerProps, type ToastContent, type ToastContentProps, type ToastIcon, type ToastItem, type ToastOptions, type ToastPosition, type ToastPromiseParams, type ToastTransition, type ToastTransitionProps, type TypeOptions, type UpdateOptions, Zoom, collapseToast, cssTransition, toast };

4
node_modules/react-toastify/dist/index.js generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/react-toastify/dist/index.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

4
node_modules/react-toastify/dist/index.mjs generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/react-toastify/dist/index.mjs.map generated vendored Normal file

File diff suppressed because one or more lines are too long

410
node_modules/react-toastify/dist/unstyled.d.mts generated vendored Normal file
View File

@@ -0,0 +1,410 @@
import * as React from 'react';
import React__default, { HTMLAttributes } from 'react';
interface CloseButtonProps {
closeToast: CloseToastFunc;
type: TypeOptions;
ariaLabel?: string;
theme: Theme;
}
declare function CloseButton({ closeToast, theme, ariaLabel }: CloseButtonProps): React__default.JSX.Element;
declare function ToastContainer(props: ToastContainerProps): React__default.JSX.Element;
declare const Bounce: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Slide: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Zoom: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Flip: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
/**
* Used when providing custom icon
*/
interface IconProps {
theme: Theme;
type: TypeOptions;
isLoading?: boolean;
}
type BuiltInIconProps = React__default.SVGProps<SVGSVGElement> & IconProps;
declare function Warning(props: BuiltInIconProps): React__default.JSX.Element;
declare function Info(props: BuiltInIconProps): React__default.JSX.Element;
declare function Success(props: BuiltInIconProps): React__default.JSX.Element;
declare function Error(props: BuiltInIconProps): React__default.JSX.Element;
declare function Spinner(): React__default.JSX.Element;
declare const Icons: {
info: typeof Info;
warning: typeof Warning;
success: typeof Success;
error: typeof Error;
spinner: typeof Spinner;
};
declare function isToastActive(id: Id, containerId?: Id): boolean;
declare const clearWaitingQueue: (p?: ClearWaitingQueueParams) => void;
type Nullable<T> = {
[P in keyof T]: T[P] | null;
};
type TypeOptions = 'info' | 'success' | 'warning' | 'error' | 'default';
type Theme = 'light' | 'dark' | 'colored' | (string & {});
type ToastPosition = 'top-right' | 'top-center' | 'top-left' | 'bottom-right' | 'bottom-center' | 'bottom-left';
type CloseToastFunc = ((reason?: boolean | string) => void) & ((e: React__default.MouseEvent) => void);
interface ToastContentProps<Data = unknown> {
closeToast: CloseToastFunc;
toastProps: ToastProps;
isPaused: boolean;
data: Data;
}
type ToastContent<T = unknown> = React__default.ReactNode | ((props: ToastContentProps<T>) => React__default.ReactNode);
type ToastIcon = false | ((props: IconProps) => React__default.ReactNode) | React__default.ReactElement<IconProps>;
type Id = number | string;
type ToastTransition = React__default.FC<ToastTransitionProps> | React__default.ComponentClass<ToastTransitionProps>;
/**
* ClassName for the elements - can take a function to build a classname or a raw string that is cx'ed to defaults
*/
type ToastClassName = ((context?: {
type?: TypeOptions;
defaultClassName?: string;
position?: ToastPosition;
rtl?: boolean;
}) => string) | string;
interface ClearWaitingQueueParams {
containerId?: Id;
}
type DraggableDirection = 'x' | 'y';
interface CommonOptions {
/**
* Pause the timer when the mouse hover the toast.
* `Default: true`
*/
pauseOnHover?: boolean;
/**
* Pause the toast when the window loses focus.
* `Default: true`
*/
pauseOnFocusLoss?: boolean;
/**
* Remove the toast when clicked.
* `Default: false`
*/
closeOnClick?: boolean;
/**
* Set the delay in ms to close the toast automatically.
* Use `false` to prevent the toast from closing.
* `Default: 5000`
*/
autoClose?: number | false;
/**
* Set the default position to use.
* `One of: 'top-right', 'top-center', 'top-left', 'bottom-right', 'bottom-center', 'bottom-left'`
* `Default: 'top-right'`
*/
position?: ToastPosition;
/**
* Pass a custom close button.
* To remove the close button pass `false`
*/
closeButton?: boolean | ((props: CloseButtonProps) => React__default.ReactNode) | React__default.ReactElement<CloseButtonProps>;
/**
* An optional css class to set for the progress bar.
*/
progressClassName?: ToastClassName;
/**
* Hide or show the progress bar.
* `Default: false`
*/
hideProgressBar?: boolean;
/**
* Pass a custom transition see https://fkhadra.github.io/react-toastify/custom-animation/
*/
transition?: ToastTransition;
/**
* Allow toast to be draggable
* `Default: 'touch'`
*/
draggable?: boolean | 'mouse' | 'touch';
/**
* The percentage of the toast's width it takes for a drag to dismiss a toast
* `Default: 80`
*/
draggablePercent?: number;
/**
* Specify in which direction should you swipe to dismiss the toast
* `Default: "x"`
*/
draggableDirection?: DraggableDirection;
/**
* Define the ARIA role for the toast
* `Default: alert`
* https://www.w3.org/WAI/PF/aria/roles
*/
role?: string;
/**
* Set id to handle multiple container
*/
containerId?: Id;
/**
* Fired when clicking inside toaster
*/
onClick?: (event: React__default.MouseEvent) => void;
/**
* Support right to left display.
* `Default: false`
*/
rtl?: boolean;
/**
* Used to display a custom icon. Set it to `false` to prevent
* the icons from being displayed
*/
icon?: ToastIcon;
/**
* Theme to use.
* `One of: 'light', 'dark', 'colored'`
* `Default: 'light'`
*/
theme?: Theme;
/**
* When set to `true` the built-in progress bar won't be rendered at all. Autoclose delay won't have any effect as well
* This is only used when you want to replace the progress bar with your own.
*
* See https://stackblitz.com/edit/react-toastify-custom-progress-bar?file=src%2FApp.tsx for an example.
*/
customProgressBar?: boolean;
}
interface ToastOptions<Data = unknown> extends CommonOptions {
/**
* An optional css class to set.
*/
className?: ToastClassName;
/**
* Called when toast is mounted.
*/
onOpen?: () => void;
/**
* Called when toast is unmounted.
* The callback first argument is the closure reason.
* It is "true" when the notification is closed by a user action like clicking on the close button.
*/
onClose?: (reason?: boolean | string) => void;
/**
* An optional inline style to apply.
*/
style?: React__default.CSSProperties;
/**
* Set the toast type.
* `One of: 'info', 'success', 'warning', 'error', 'default'`
*/
type?: TypeOptions;
/**
* Set a custom `toastId`
*/
toastId?: Id;
/**
* Used during update
*/
updateId?: Id;
/**
* Set the percentage for the controlled progress bar. `Value must be between 0 and 1.`
*/
progress?: number;
/**
* Let you provide any data, useful when you are using your own component
*/
data?: Data;
/**
* Let you specify the aria-label
*/
ariaLabel?: string;
/**
* Add a delay in ms before the toast appear.
*/
delay?: number;
isLoading?: boolean;
}
interface UpdateOptions<T = unknown> extends Nullable<ToastOptions<T>> {
/**
* Used to update a toast.
* Pass any valid ReactNode(string, number, component)
*/
render?: ToastContent<T>;
}
interface ToastContainerProps extends CommonOptions, Pick<HTMLAttributes<HTMLElement>, 'aria-label'> {
/**
* An optional css class to set.
*/
className?: ToastClassName;
/**
* Will stack the toast with the newest on the top.
*/
stacked?: boolean;
/**
* Whether or not to display the newest toast on top.
* `Default: false`
*/
newestOnTop?: boolean;
/**
* An optional inline style to apply.
*/
style?: React__default.CSSProperties;
/**
* An optional inline style to apply for the toast.
*/
toastStyle?: React__default.CSSProperties;
/**
* An optional css class for the toast.
*/
toastClassName?: ToastClassName;
/**
* Limit the number of toast displayed at the same time
*/
limit?: number;
/**
* Shortcut to focus the first notification with the keyboard
* `default: Alt+t`
*
* ```
* // focus when user presses ⌘ + F
* const matchShortcut = (e: KeyboardEvent) => e.metaKey && e.key === 'f'
* ```
*/
hotKeys?: (e: KeyboardEvent) => boolean;
}
interface ToastTransitionProps {
isIn: boolean;
done: () => void;
position: ToastPosition | string;
preventExitTransition: boolean;
nodeRef: React__default.RefObject<HTMLElement>;
children?: React__default.ReactNode;
playToast(): void;
}
/**
* @INTERNAL
*/
interface ToastProps extends ToastOptions {
isIn: boolean;
staleId?: Id;
toastId: Id;
key: Id;
transition: ToastTransition;
closeToast: CloseToastFunc;
position: ToastPosition;
children?: ToastContent;
draggablePercent: number;
draggableDirection?: DraggableDirection;
progressClassName?: ToastClassName;
className?: ToastClassName;
deleteToast: () => void;
theme: Theme;
type: TypeOptions;
collapseAll: () => void;
stacked?: boolean;
}
type ToastItemStatus = 'added' | 'removed' | 'updated';
interface ToastItem<Data = {}> {
content: ToastContent<Data>;
id: Id;
theme?: Theme;
type?: TypeOptions;
isLoading?: boolean;
containerId?: Id;
data: Data;
icon?: ToastIcon;
status: ToastItemStatus;
reason?: boolean | string;
}
type OnChangeCallback = (toast: ToastItem) => void;
type IdOpts = {
id?: Id;
containerId?: Id;
};
type ClearWaitingQueueFunc = typeof clearWaitingQueue;
declare const enum Default {
COLLAPSE_DURATION = 300,
DEBOUNCE_DURATION = 50,
CSS_NAMESPACE = "Toastify",
DRAGGABLE_PERCENT = 80,
CONTAINER_ID = 1
}
interface CSSTransitionProps {
/**
* Css class to apply when toast enter
*/
enter: string;
/**
* Css class to apply when toast leave
*/
exit: string;
/**
* Append current toast position to the classname.
* If multiple classes are provided, only the last one will get the position
* For instance `myclass--top-center`...
* `Default: false`
*/
appendPosition?: boolean;
/**
* Collapse toast smoothly when exit animation end
* `Default: true`
*/
collapse?: boolean;
/**
* Collapse transition duration
* `Default: 300`
*/
collapseDuration?: number;
}
/**
* Css animation that just work.
* You could use animate.css for instance
*
*
* ```
* cssTransition({
* enter: "animate__animated animate__bounceIn",
* exit: "animate__animated animate__bounceOut"
* })
* ```
*
*/
declare function cssTransition({ enter, exit, appendPosition, collapse, collapseDuration }: CSSTransitionProps): ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React__default.JSX.Element;
/**
* Used to collapse toast after exit animation
*/
declare function collapseToast(node: HTMLElement, done: () => void, duration?: Default): void;
declare function toast<TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>): Id;
declare namespace toast {
var loading: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var promise: typeof handlePromise;
var success: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var info: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var error: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var warning: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var warn: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var dark: (content: ToastContent, options?: ToastOptions) => Id;
var dismiss: {
(params: RemoveParams): void;
(params?: Id): void;
};
var clearWaitingQueue: (p?: ClearWaitingQueueParams) => void;
var isActive: typeof isToastActive;
var update: <TData = unknown>(toastId: Id, options?: UpdateOptions<TData>) => void;
var done: (id: Id) => void;
var onChange: (cb: OnChangeCallback) => () => void;
var play: (opts?: IdOpts) => void;
var pause: (opts?: IdOpts) => void;
}
interface ToastPromiseParams<TData = unknown, TError = unknown, TPending = unknown> {
pending?: string | UpdateOptions<TPending>;
success?: string | UpdateOptions<TData>;
error?: string | UpdateOptions<TError>;
}
declare function handlePromise<TData = unknown, TError = unknown, TPending = unknown>(promise: Promise<TData> | (() => Promise<TData>), { pending, error, success }: ToastPromiseParams<TData, TError, TPending>, options?: ToastOptions<TData>): Promise<TData>;
interface RemoveParams {
id?: Id;
containerId: Id;
}
export { Bounce, type ClearWaitingQueueFunc, type ClearWaitingQueueParams, CloseButton, type CloseButtonProps, type DraggableDirection, Flip, type IconProps, Icons, type Id, type OnChangeCallback, Slide, type Theme, type ToastClassName, ToastContainer, type ToastContainerProps, type ToastContent, type ToastContentProps, type ToastIcon, type ToastItem, type ToastOptions, type ToastPosition, type ToastPromiseParams, type ToastTransition, type ToastTransitionProps, type TypeOptions, type UpdateOptions, Zoom, collapseToast, cssTransition, toast };

410
node_modules/react-toastify/dist/unstyled.d.ts generated vendored Normal file
View File

@@ -0,0 +1,410 @@
import * as React from 'react';
import React__default, { HTMLAttributes } from 'react';
interface CloseButtonProps {
closeToast: CloseToastFunc;
type: TypeOptions;
ariaLabel?: string;
theme: Theme;
}
declare function CloseButton({ closeToast, theme, ariaLabel }: CloseButtonProps): React__default.JSX.Element;
declare function ToastContainer(props: ToastContainerProps): React__default.JSX.Element;
declare const Bounce: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Slide: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Zoom: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
declare const Flip: ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React.JSX.Element;
/**
* Used when providing custom icon
*/
interface IconProps {
theme: Theme;
type: TypeOptions;
isLoading?: boolean;
}
type BuiltInIconProps = React__default.SVGProps<SVGSVGElement> & IconProps;
declare function Warning(props: BuiltInIconProps): React__default.JSX.Element;
declare function Info(props: BuiltInIconProps): React__default.JSX.Element;
declare function Success(props: BuiltInIconProps): React__default.JSX.Element;
declare function Error(props: BuiltInIconProps): React__default.JSX.Element;
declare function Spinner(): React__default.JSX.Element;
declare const Icons: {
info: typeof Info;
warning: typeof Warning;
success: typeof Success;
error: typeof Error;
spinner: typeof Spinner;
};
declare function isToastActive(id: Id, containerId?: Id): boolean;
declare const clearWaitingQueue: (p?: ClearWaitingQueueParams) => void;
type Nullable<T> = {
[P in keyof T]: T[P] | null;
};
type TypeOptions = 'info' | 'success' | 'warning' | 'error' | 'default';
type Theme = 'light' | 'dark' | 'colored' | (string & {});
type ToastPosition = 'top-right' | 'top-center' | 'top-left' | 'bottom-right' | 'bottom-center' | 'bottom-left';
type CloseToastFunc = ((reason?: boolean | string) => void) & ((e: React__default.MouseEvent) => void);
interface ToastContentProps<Data = unknown> {
closeToast: CloseToastFunc;
toastProps: ToastProps;
isPaused: boolean;
data: Data;
}
type ToastContent<T = unknown> = React__default.ReactNode | ((props: ToastContentProps<T>) => React__default.ReactNode);
type ToastIcon = false | ((props: IconProps) => React__default.ReactNode) | React__default.ReactElement<IconProps>;
type Id = number | string;
type ToastTransition = React__default.FC<ToastTransitionProps> | React__default.ComponentClass<ToastTransitionProps>;
/**
* ClassName for the elements - can take a function to build a classname or a raw string that is cx'ed to defaults
*/
type ToastClassName = ((context?: {
type?: TypeOptions;
defaultClassName?: string;
position?: ToastPosition;
rtl?: boolean;
}) => string) | string;
interface ClearWaitingQueueParams {
containerId?: Id;
}
type DraggableDirection = 'x' | 'y';
interface CommonOptions {
/**
* Pause the timer when the mouse hover the toast.
* `Default: true`
*/
pauseOnHover?: boolean;
/**
* Pause the toast when the window loses focus.
* `Default: true`
*/
pauseOnFocusLoss?: boolean;
/**
* Remove the toast when clicked.
* `Default: false`
*/
closeOnClick?: boolean;
/**
* Set the delay in ms to close the toast automatically.
* Use `false` to prevent the toast from closing.
* `Default: 5000`
*/
autoClose?: number | false;
/**
* Set the default position to use.
* `One of: 'top-right', 'top-center', 'top-left', 'bottom-right', 'bottom-center', 'bottom-left'`
* `Default: 'top-right'`
*/
position?: ToastPosition;
/**
* Pass a custom close button.
* To remove the close button pass `false`
*/
closeButton?: boolean | ((props: CloseButtonProps) => React__default.ReactNode) | React__default.ReactElement<CloseButtonProps>;
/**
* An optional css class to set for the progress bar.
*/
progressClassName?: ToastClassName;
/**
* Hide or show the progress bar.
* `Default: false`
*/
hideProgressBar?: boolean;
/**
* Pass a custom transition see https://fkhadra.github.io/react-toastify/custom-animation/
*/
transition?: ToastTransition;
/**
* Allow toast to be draggable
* `Default: 'touch'`
*/
draggable?: boolean | 'mouse' | 'touch';
/**
* The percentage of the toast's width it takes for a drag to dismiss a toast
* `Default: 80`
*/
draggablePercent?: number;
/**
* Specify in which direction should you swipe to dismiss the toast
* `Default: "x"`
*/
draggableDirection?: DraggableDirection;
/**
* Define the ARIA role for the toast
* `Default: alert`
* https://www.w3.org/WAI/PF/aria/roles
*/
role?: string;
/**
* Set id to handle multiple container
*/
containerId?: Id;
/**
* Fired when clicking inside toaster
*/
onClick?: (event: React__default.MouseEvent) => void;
/**
* Support right to left display.
* `Default: false`
*/
rtl?: boolean;
/**
* Used to display a custom icon. Set it to `false` to prevent
* the icons from being displayed
*/
icon?: ToastIcon;
/**
* Theme to use.
* `One of: 'light', 'dark', 'colored'`
* `Default: 'light'`
*/
theme?: Theme;
/**
* When set to `true` the built-in progress bar won't be rendered at all. Autoclose delay won't have any effect as well
* This is only used when you want to replace the progress bar with your own.
*
* See https://stackblitz.com/edit/react-toastify-custom-progress-bar?file=src%2FApp.tsx for an example.
*/
customProgressBar?: boolean;
}
interface ToastOptions<Data = unknown> extends CommonOptions {
/**
* An optional css class to set.
*/
className?: ToastClassName;
/**
* Called when toast is mounted.
*/
onOpen?: () => void;
/**
* Called when toast is unmounted.
* The callback first argument is the closure reason.
* It is "true" when the notification is closed by a user action like clicking on the close button.
*/
onClose?: (reason?: boolean | string) => void;
/**
* An optional inline style to apply.
*/
style?: React__default.CSSProperties;
/**
* Set the toast type.
* `One of: 'info', 'success', 'warning', 'error', 'default'`
*/
type?: TypeOptions;
/**
* Set a custom `toastId`
*/
toastId?: Id;
/**
* Used during update
*/
updateId?: Id;
/**
* Set the percentage for the controlled progress bar. `Value must be between 0 and 1.`
*/
progress?: number;
/**
* Let you provide any data, useful when you are using your own component
*/
data?: Data;
/**
* Let you specify the aria-label
*/
ariaLabel?: string;
/**
* Add a delay in ms before the toast appear.
*/
delay?: number;
isLoading?: boolean;
}
interface UpdateOptions<T = unknown> extends Nullable<ToastOptions<T>> {
/**
* Used to update a toast.
* Pass any valid ReactNode(string, number, component)
*/
render?: ToastContent<T>;
}
interface ToastContainerProps extends CommonOptions, Pick<HTMLAttributes<HTMLElement>, 'aria-label'> {
/**
* An optional css class to set.
*/
className?: ToastClassName;
/**
* Will stack the toast with the newest on the top.
*/
stacked?: boolean;
/**
* Whether or not to display the newest toast on top.
* `Default: false`
*/
newestOnTop?: boolean;
/**
* An optional inline style to apply.
*/
style?: React__default.CSSProperties;
/**
* An optional inline style to apply for the toast.
*/
toastStyle?: React__default.CSSProperties;
/**
* An optional css class for the toast.
*/
toastClassName?: ToastClassName;
/**
* Limit the number of toast displayed at the same time
*/
limit?: number;
/**
* Shortcut to focus the first notification with the keyboard
* `default: Alt+t`
*
* ```
* // focus when user presses ⌘ + F
* const matchShortcut = (e: KeyboardEvent) => e.metaKey && e.key === 'f'
* ```
*/
hotKeys?: (e: KeyboardEvent) => boolean;
}
interface ToastTransitionProps {
isIn: boolean;
done: () => void;
position: ToastPosition | string;
preventExitTransition: boolean;
nodeRef: React__default.RefObject<HTMLElement>;
children?: React__default.ReactNode;
playToast(): void;
}
/**
* @INTERNAL
*/
interface ToastProps extends ToastOptions {
isIn: boolean;
staleId?: Id;
toastId: Id;
key: Id;
transition: ToastTransition;
closeToast: CloseToastFunc;
position: ToastPosition;
children?: ToastContent;
draggablePercent: number;
draggableDirection?: DraggableDirection;
progressClassName?: ToastClassName;
className?: ToastClassName;
deleteToast: () => void;
theme: Theme;
type: TypeOptions;
collapseAll: () => void;
stacked?: boolean;
}
type ToastItemStatus = 'added' | 'removed' | 'updated';
interface ToastItem<Data = {}> {
content: ToastContent<Data>;
id: Id;
theme?: Theme;
type?: TypeOptions;
isLoading?: boolean;
containerId?: Id;
data: Data;
icon?: ToastIcon;
status: ToastItemStatus;
reason?: boolean | string;
}
type OnChangeCallback = (toast: ToastItem) => void;
type IdOpts = {
id?: Id;
containerId?: Id;
};
type ClearWaitingQueueFunc = typeof clearWaitingQueue;
declare const enum Default {
COLLAPSE_DURATION = 300,
DEBOUNCE_DURATION = 50,
CSS_NAMESPACE = "Toastify",
DRAGGABLE_PERCENT = 80,
CONTAINER_ID = 1
}
interface CSSTransitionProps {
/**
* Css class to apply when toast enter
*/
enter: string;
/**
* Css class to apply when toast leave
*/
exit: string;
/**
* Append current toast position to the classname.
* If multiple classes are provided, only the last one will get the position
* For instance `myclass--top-center`...
* `Default: false`
*/
appendPosition?: boolean;
/**
* Collapse toast smoothly when exit animation end
* `Default: true`
*/
collapse?: boolean;
/**
* Collapse transition duration
* `Default: 300`
*/
collapseDuration?: number;
}
/**
* Css animation that just work.
* You could use animate.css for instance
*
*
* ```
* cssTransition({
* enter: "animate__animated animate__bounceIn",
* exit: "animate__animated animate__bounceOut"
* })
* ```
*
*/
declare function cssTransition({ enter, exit, appendPosition, collapse, collapseDuration }: CSSTransitionProps): ({ children, position, preventExitTransition, done, nodeRef, isIn, playToast }: ToastTransitionProps) => React__default.JSX.Element;
/**
* Used to collapse toast after exit animation
*/
declare function collapseToast(node: HTMLElement, done: () => void, duration?: Default): void;
declare function toast<TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>): Id;
declare namespace toast {
var loading: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var promise: typeof handlePromise;
var success: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var info: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var error: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var warning: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var warn: <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) => Id;
var dark: (content: ToastContent, options?: ToastOptions) => Id;
var dismiss: {
(params: RemoveParams): void;
(params?: Id): void;
};
var clearWaitingQueue: (p?: ClearWaitingQueueParams) => void;
var isActive: typeof isToastActive;
var update: <TData = unknown>(toastId: Id, options?: UpdateOptions<TData>) => void;
var done: (id: Id) => void;
var onChange: (cb: OnChangeCallback) => () => void;
var play: (opts?: IdOpts) => void;
var pause: (opts?: IdOpts) => void;
}
interface ToastPromiseParams<TData = unknown, TError = unknown, TPending = unknown> {
pending?: string | UpdateOptions<TPending>;
success?: string | UpdateOptions<TData>;
error?: string | UpdateOptions<TError>;
}
declare function handlePromise<TData = unknown, TError = unknown, TPending = unknown>(promise: Promise<TData> | (() => Promise<TData>), { pending, error, success }: ToastPromiseParams<TData, TError, TPending>, options?: ToastOptions<TData>): Promise<TData>;
interface RemoveParams {
id?: Id;
containerId: Id;
}
export { Bounce, type ClearWaitingQueueFunc, type ClearWaitingQueueParams, CloseButton, type CloseButtonProps, type DraggableDirection, Flip, type IconProps, Icons, type Id, type OnChangeCallback, Slide, type Theme, type ToastClassName, ToastContainer, type ToastContainerProps, type ToastContent, type ToastContentProps, type ToastIcon, type ToastItem, type ToastOptions, type ToastPosition, type ToastPromiseParams, type ToastTransition, type ToastTransitionProps, type TypeOptions, type UpdateOptions, Zoom, collapseToast, cssTransition, toast };

3
node_modules/react-toastify/dist/unstyled.js generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/react-toastify/dist/unstyled.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

3
node_modules/react-toastify/dist/unstyled.mjs generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/react-toastify/dist/unstyled.mjs.map generated vendored Normal file

File diff suppressed because one or more lines are too long

107
node_modules/react-toastify/package.json generated vendored Normal file
View File

@@ -0,0 +1,107 @@
{
"version": "11.0.5",
"license": "MIT",
"description": "React notification made easy",
"keywords": [
"react",
"notification",
"toast",
"react-component",
"react-toastify",
"push",
"alert",
"snackbar",
"message"
],
"files": [
"dist",
"addons"
],
"scripts": {
"prepare": "lefthook install",
"setup": "pnpm link .",
"start": "cd playground && pnpm dev",
"test": "cypress open --component",
"test:run": "cypress run --component -b chrome",
"prettier": "prettier --write src",
"build": "tsup && cp src/style.css dist/ReactToastify.css && rm dist/unstyled.css*"
},
"peerDependencies": {
"react": "^18 || ^19",
"react-dom": "^18 || ^19"
},
"prettier": {
"printWidth": 120,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"arrowParens": "avoid"
},
"name": "react-toastify",
"repository": {
"type": "git",
"url": "git+https://github.com/fkhadra/react-toastify.git"
},
"author": "Fadi Khadra <fdkhadra@gmail.com> (https://fkhadra.github.io)",
"bugs": {
"url": "https://github.com/fkhadra/react-toastify/issues"
},
"homepage": "https://github.com/fkhadra/react-toastify#readme",
"devDependencies": {
"@4tw/cypress-drag-drop": "^2.2.5",
"@cypress/code-coverage": "^3.13.9",
"@istanbuljs/nyc-config-typescript": "^1.0.2",
"@testing-library/cypress": "^10.0.2",
"@types/node": "^22.10.2",
"@types/react": "^19.0.1",
"@types/react-dom": "^19.0.2",
"@vitejs/plugin-react": "^4.3.4",
"coveralls": "^3.1.1",
"cypress": "^13.16.1",
"lefthook": "^1.9.2",
"lint-staged": "^15.2.11",
"postcss": "^8.4.49",
"prettier": "3.4.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"tsup": "^8.3.5",
"typescript": "^5.7.2",
"vite": "^6.0.3",
"vite-plugin-istanbul": "^6.0.2"
},
"dependencies": {
"clsx": "^2.1.1"
},
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"module": "dist/index.mjs",
"source": "src/index.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./unstyled": {
"types": "./dist/unstyled.d.ts",
"import": "./dist/unstyled.mjs",
"require": "./dist/unstyled.js"
},
"./dist/ReactToastify.css": "./dist/ReactToastify.css",
"./ReactToastify.css": "./dist/ReactToastify.css",
"./package.json": "./package.json",
"./addons/use-notification-center": {
"types": "./addons/use-notification-center/index.d.ts",
"import": "./addons/use-notification-center/index.mjs",
"require": "./addons/use-notification-center/index.js"
},
"./notification-center": {
"types": "./addons/use-notification-center/index.d.ts",
"import": "./addons/use-notification-center/index.mjs",
"require": "./addons/use-notification-center/index.js"
}
},
"lint-staged": {
"*.{js,jsx,ts,tsx,md,html,css}": "prettier --write"
}
}

13
package-lock.json generated
View File

@@ -13,6 +13,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.8.1",
"react-toastify": "^11.0.5",
"recharts": "^2.5.0",
"zustand": "^5.0.8"
},
@@ -4283,6 +4284,18 @@
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-toastify": {
"version": "11.0.5",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.5.tgz",
"integrity": "sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==",
"dependencies": {
"clsx": "^2.1.1"
},
"peerDependencies": {
"react": "^18 || ^19",
"react-dom": "^18 || ^19"
}
},
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",

View File

@@ -15,6 +15,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.8.1",
"react-toastify": "^11.0.5",
"recharts": "^2.5.0",
"zustand": "^5.0.8"
},

View File

@@ -9,6 +9,7 @@ import Transactions from './pages/Transactions';
import Settings from './pages/Settings';
import ForgotPassword from './pages/ForgotPassword';
import Roles from './pages/Roles';
import Users from './pages/Users';
// Protected Route Component
const ProtectedRoute = ({ children }) => {
@@ -102,6 +103,19 @@ const AppRoutes = () => {
</ProtectedRoute>
}
/>
<Route
path="/users"
element={
<ProtectedRoute>
<Layout>
<Users/>
</Layout>
</ProtectedRoute>
}
/>
<Route path="*" element={<Navigate to="/" />} />
</Routes>
);

View File

@@ -1,7 +1,270 @@
import React from 'react'
import React, { useEffect, useMemo, useState } from 'react';
import DataTable from '../components/DataTable';
import { usersAPI } from '../services/api';
import { Plus, Trash2, Search, Pencil, ShieldOff, RefreshCcw } from 'lucide-react';
const Users = () => {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [email, setEmail] = useState('');
const [filter, setFilter] = useState('');
const [isModalOpen, setIsModalOpen] = useState(false);
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [editingUser, setEditingUser] = useState(null);
const fetchUsers = async (q = '') => {
try {
setLoading(true);
const list = await usersAPI.list(q);
setUsers(Array.isArray(list) ? list : []);
} catch (e) {
setError('Failed to load users');
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchUsers();
}, []);
const onAddUser = async (e) => {
e.preventDefault();
if (!firstName.trim() || !lastName.trim() || !email.trim()) return;
try {
await usersAPI.create({ firstName, lastName, email });
setFirstName('');
setLastName('');
setEmail('');
await fetchUsers(filter);
setIsModalOpen(false);
} catch (_) {
setError('Failed to create user');
}
};
const onDelete = async (id) => {
if (!window.confirm('Are you sure you want to delete this user?')) return;
await usersAPI.remove(id);
await fetchUsers(filter);
};
const openEdit = (user) => {
setEditingUser(user);
setFirstName(user.firstName || '');
setLastName(user.lastName || '');
setEmail(user.email || '');
setIsEditModalOpen(true);
};
const onUpdateUser = async (e) => {
e.preventDefault();
if (!editingUser) return;
try {
await usersAPI.update(editingUser.id, { firstName, lastName, email });
await fetchUsers(filter);
setIsEditModalOpen(false);
setEditingUser(null);
setFirstName('');
setLastName('');
setEmail('');
} catch (_) {
setError('Failed to update user');
}
};
const onToggleActivation = async (id) => {
await usersAPI.toggleActivation(id);
await fetchUsers(filter);
};
const onResetPassword = async (id) => {
await usersAPI.resetPassword(id);
alert('Password reset successfully.');
};
const columns = useMemo(() => [
{ key: 'firstName', header: 'First Name' },
{ key: 'lastName', header: 'Last Name' },
{ key: 'email', header: 'Email' },
{ key: 'isActive', header: 'Active', render: (val) => val ? '✅' : '❌' },
{
key: 'actions',
header: 'Actions',
render: (_val, row) => (
<div className="flex items-center gap-x-2">
<button
onClick={() => openEdit(row)}
className="inline-flex items-center px-3 py-1 text-sm rounded-md bg-blue-100 text-blue-700 hover:opacity-90"
>
<Pencil className="h-4 w-4 mr-1" /> Edit
</button>
<button
onClick={() => onDelete(row.id)}
className="inline-flex items-center px-3 py-1 text-sm rounded-md bg-red-100 text-red-700 hover:opacity-90"
>
<Trash2 className="h-4 w-4 mr-1" /> Delete
</button>
<button
onClick={() => onToggleActivation(row.id)}
className="inline-flex items-center px-3 py-1 text-sm rounded-md bg-gray-100 text-gray-700 hover:opacity-90"
>
<ShieldOff className="h-4 w-4 mr-1" /> Toggle
</button>
<button
onClick={() => onResetPassword(row.id)}
className="inline-flex items-center px-3 py-1 text-sm rounded-md bg-green-100 text-green-700 hover:opacity-90"
>
<RefreshCcw className="h-4 w-4 mr-1" /> Reset
</button>
</div>
),
},
], []);
export default function Users() {
return (
<div>Users</div>
)
}
<div className="p-6">
<div className="mb-6 flex items-start justify-between">
<div>
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">Users</h1>
<p className="text-gray-600 dark:text-gray-400">
Manage users: add, edit, activate/deactivate and reset password
</p>
</div>
<button
onClick={() => setIsModalOpen(true)}
className="btn-primary inline-flex items-center"
>
<Plus className="h-4 w-4 mr-2" /> Add User
</button>
</div>
{/* Add Modal */}
{isModalOpen && (
<>
<div
className="fixed inset-0 bg-black bg-opacity-50 z-40"
onClick={() => setIsModalOpen(false)}
/>
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
<div className="w-full max-w-md card p-6 relative">
<h3 className="text-lg font-semibold text-gray-900 mb-4">Add User</h3>
<form className="space-y-4" onSubmit={onAddUser}>
<input
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
className="w-full p-2 border rounded-lg"
placeholder="First Name"
/>
<input
value={lastName}
onChange={(e) => setLastName(e.target.value)}
className="w-full p-2 border rounded-lg"
placeholder="Last Name"
/>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full p-2 border rounded-lg"
placeholder="Email"
/>
<div className="flex justify-end gap-x-2">
<button
type="button"
onClick={() => setIsModalOpen(false)}
className="px-4 py-2 border rounded-lg"
>
Cancel
</button>
<button type="submit" className="btn-primary px-4 py-2 rounded-lg">
Add
</button>
</div>
</form>
</div>
</div>
</>
)}
{/* Edit Modal */}
{isEditModalOpen && (
<>
<div
className="fixed inset-0 bg-black bg-opacity-50 z-40"
onClick={() => setIsEditModalOpen(false)}
/>
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
<div className="w-full max-w-md card p-6 relative">
<h3 className="text-lg font-semibold text-gray-900 mb-4">Edit User</h3>
<form className="space-y-4" onSubmit={onUpdateUser}>
<input
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
className="w-full p-2 border rounded-lg"
placeholder="First Name"
/>
<input
value={lastName}
onChange={(e) => setLastName(e.target.value)}
className="w-full p-2 border rounded-lg"
placeholder="Last Name"
/>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full p-2 border rounded-lg"
placeholder="Email"
/>
<div className="flex justify-end gap-x-2">
<button
type="button"
onClick={() => setIsEditModalOpen(false)}
className="px-4 py-2 border rounded-lg"
>
Cancel
</button>
<button type="submit" className="btn-primary px-4 py-2 rounded-lg">
Update
</button>
</div>
</form>
</div>
</div>
</>
)}
{/* Filter */}
<div className="card p-4 mb-4">
<div className="relative max-w-md">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
<input
value={filter}
onChange={async (e) => {
const v = e.target.value;
setFilter(v);
await fetchUsers(v);
}}
placeholder="Filter by name or email"
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500"
/>
</div>
</div>
<DataTable
data={users}
columns={columns}
loading={loading}
searchable={false}
/>
{error && (
<div className="mt-4 text-sm text-red-600">{error}</div>
)}
</div>
);
};
export default Users;

View File

@@ -318,6 +318,177 @@ export const rolesAPI = {
},
};
// -----------------------------
// ✅ Users API (React version)
// -----------------------------
const USERS_STORAGE_KEY = 'app_users_v1';
// 🧩 localStorage helpers
function readUsersFromStorage() {
try {
const raw = localStorage.getItem(USERS_STORAGE_KEY);
if (!raw) return [];
const parsed = JSON.parse(raw);
return Array.isArray(parsed) ? parsed : [];
} catch {
return [];
}
}
function writeUsersToStorage(users) {
localStorage.setItem(USERS_STORAGE_KEY, JSON.stringify(users));
}
export const usersAPI = {
// 📄 لیست کاربران
async list({ searchQuery = '', currentPage = 1, pageSize = 100 } = {}) {
try {
const res = await api.get('/api/v1/User', {
params: { searchQuery, currentPage, pageSize },
skipAuthRedirect: true,
});
const apiItems = Array.isArray(res?.data?.data?.data)
? res.data.data.data
: [];
writeUsersToStorage(apiItems);
return apiItems;
} catch (err) {
console.warn('List users fallback to localStorage');
const users = readUsersFromStorage();
const trimmed = searchQuery.toLowerCase();
return trimmed
? users.filter(
(u) =>
u.firstName?.toLowerCase().includes(trimmed) ||
u.lastName?.toLowerCase().includes(trimmed) ||
u.email?.toLowerCase().includes(trimmed)
)
: users;
}
},
// افزودن کاربر جدید
async create(user) {
const payload = {
firstName: String(user?.firstName || '').trim(),
lastName: String(user?.lastName || '').trim(),
email: String(user?.email || '').trim(),
mobile: String(user?.mobile || '').trim(),
isActive: !!user?.isActive,
};
try {
const res = await api.post('/api/v1/User', payload, { skipAuthRedirect: true });
const created = res?.data?.data || payload;
const users = readUsersFromStorage();
const newUser = { id: created.id || crypto.randomUUID(), ...created };
users.push(newUser);
writeUsersToStorage(users);
return newUser;
} catch (err) {
console.error('Create user failed', err);
const fallbackUser = { id: crypto.randomUUID(), ...payload };
const users = readUsersFromStorage();
users.push(fallbackUser);
writeUsersToStorage(users);
return fallbackUser;
}
},
// ✏️ ویرایش کاربر
async update(id, user) {
const payload = {
firstName: String(user?.firstName || '').trim(),
lastName: String(user?.lastName || '').trim(),
email: String(user?.email || '').trim(),
mobile: String(user?.mobile || '').trim(),
isActive: !!user?.isActive,
};
try {
await api.put(`/api/v1/User/${encodeURIComponent(id)}`, payload, { skipAuthRedirect: true });
} catch (err) {
console.error('Update user failed', err);
}
const users = readUsersFromStorage();
const idx = users.findIndex((u) => u.id === id);
if (idx !== -1) users[idx] = { ...users[idx], ...payload };
else users.push({ id, ...payload });
writeUsersToStorage(users);
return users[idx] || payload;
},
// ❌ حذف کاربر
async remove(id) {
try {
await api.delete(`/api/v1/User/Delete/${encodeURIComponent(id)}/Role`, {
skipAuthRedirect: true,
});
} catch (err) {
console.error('Delete user failed', err);
}
const users = readUsersFromStorage().filter((u) => u.id !== id);
writeUsersToStorage(users);
return { success: true };
},
// 🔄 تغییر وضعیت فعال بودن (PATCH)
async toggleActivation(id) {
try {
const res = await api.patch(`/api/v1/User/${encodeURIComponent(id)}/ToggleActivation`, null, {
skipAuthRedirect: true,
});
const updated = res?.data?.data;
if (updated) {
const users = readUsersFromStorage();
const idx = users.findIndex((u) => u.id === id);
if (idx !== -1) {
users[idx] = { ...users[idx], isActive: updated.isActive };
writeUsersToStorage(users);
}
}
return updated;
} catch (err) {
console.error('Toggle activation failed', err);
throw err;
}
},
// 🔐 ریست پسورد (PATCH)
async resetPassword(id) {
try {
const res = await api.patch(`/api/v1/User/${encodeURIComponent(id)}/ResetPassword`, null, {
skipAuthRedirect: true,
});
return res?.data;
} catch (err) {
console.error('Reset password failed', err);
throw err;
}
},
};
// -----------------------------
// Permissions API
// -----------------------------