diff --git a/payment-iq/app/components/test/test1.tsx b/payment-iq/app/components/test/test1.tsx new file mode 100644 index 0000000..5a9accf --- /dev/null +++ b/payment-iq/app/components/test/test1.tsx @@ -0,0 +1,103 @@ +import * as React from "react"; +import Box from "@mui/material/Box"; +import Drawer from "@mui/material/Drawer"; +import Button from "@mui/material/Button"; +import List from "@mui/material/List"; +import Divider from "@mui/material/Divider"; +import ListItem from "@mui/material/ListItem"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import ListItemText from "@mui/material/ListItemText"; +import InboxIcon from "@mui/icons-material/MoveToInbox"; +import MailIcon from "@mui/icons-material/Mail"; +import SearchIcon from "@mui/icons-material/Search"; + +export default function RightTemporaryDrawer() { + const [open, setOpen] = React.useState(false); + + const toggleDrawer = + (open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => { + if ( + event.type === "keydown" && + ((event as React.KeyboardEvent).key === "Tab" || + (event as React.KeyboardEvent).key === "Shift") + ) { + return; + } + + setOpen(open); + }; + + const list = () => ( + + + {["Inbox", "Starred", "Send email", "Drafts"].map((text, index) => ( + + + + {index % 2 === 0 ? : } + + + + + ))} + + + + {["All mail", "Trash", "Spam"].map((text, index) => ( + + + + {index % 2 === 0 ? : } + + + + + ))} + + + ); + + return ( +
+ + {/* */} + + {list()} + +
+ ); +} diff --git a/payment-iq/app/components/test/test2.tsx b/payment-iq/app/components/test/test2.tsx new file mode 100644 index 0000000..631ba38 --- /dev/null +++ b/payment-iq/app/components/test/test2.tsx @@ -0,0 +1,207 @@ +import React, { useState } from "react"; +import { + Box, + Grid, + TextField, + MenuItem, + Button, + InputLabel, + FormControl, + Select, + Typography, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; +import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import SearchIcon from "@mui/icons-material/Search"; +import RefreshIcon from "@mui/icons-material/Refresh"; + +const currencies = ["USD", "EUR", "GBP"]; +const states = ["Pending", "Completed", "Failed"]; +const transactionTypes = ["Credit", "Debit"]; +const paymentMethods = ["Card", "Bank Transfer"]; +const psps = ["Stripe", "PayPal"]; +const merchants = ["Amazon", "eBay"]; + +export default function SearchFilterForm() { + const [form, setForm] = useState({ + keyword: "", + transactionId: "", + transactionReferenceId: "", + user: "", + currency: "", + state: "", + statusDescription: "", + transactionType: "", + paymentMethod: "", + psps: "", + initialPsps: "", + merchants: "", + startDate: null, + endDate: null, + lastUpdatedFrom: null, + lastUpdatedTo: null, + minAmount: "", + maxAmount: "", + channel: "", + }); + + const handleChange = (field: string, value: any) => { + setForm((prev) => ({ ...prev, [field]: value })); + }; + + const resetForm = () => { + setForm({ + keyword: "", + transactionId: "", + transactionReferenceId: "", + user: "", + currency: "", + state: "", + statusDescription: "", + transactionType: "", + paymentMethod: "", + psps: "", + initialPsps: "", + merchants: "", + startDate: null, + endDate: null, + lastUpdatedFrom: null, + lastUpdatedTo: null, + minAmount: "", + maxAmount: "", + channel: "", + }); + }; + + return ( + + + + Search + + + + {[ + { label: "Keyword", field: "keyword", type: "text" }, + { label: "Transaction ID", field: "transactionId", type: "text" }, + { + label: "Transaction Reference ID", + field: "transactionReferenceId", + type: "text", + }, + { label: "User", field: "user", type: "text" }, + { + label: "Currency", + field: "currency", + type: "select", + options: currencies, + }, + { label: "State", field: "state", type: "select", options: states }, + { + label: "Status Description", + field: "statusDescription", + type: "text", + }, + { + label: "Transaction Type", + field: "transactionType", + type: "select", + options: transactionTypes, + }, + { + label: "Payment Method", + field: "paymentMethod", + type: "select", + options: paymentMethods, + }, + { label: "PSPs", field: "psps", type: "text" }, + { label: "Initial PSPs", field: "initialPsps", type: "text" }, + { label: "Merchants", field: "merchants", type: "text" }, + { label: "Start Date", field: "startDate", type: "date" }, + { label: "End Date", field: "endDate", type: "date" }, + { + label: "Last Updated From", + field: "lastUpdatedFrom", + type: "date", + }, + { label: "Last Updated To", field: "lastUpdatedTo", type: "date" }, + { label: "Min Amount", field: "minAmount", type: "text" }, + { label: "Max Amount", field: "maxAmount", type: "text" }, + { label: "Channel", field: "channel", type: "text" }, + ].map(({ label, field, type, options }) => ( + + + + {label} + + + + {type === "text" && ( + handleChange(field, e.target.value)} + /> + )} + {type === "select" && ( + + + + )} + {type === "date" && ( + handleChange(field, newValue)} + renderInput={(params) => ( + + )} + /> + )} + + + ))} + + {/* Buttons */} + + + + + + + + ); +} diff --git a/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx b/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx new file mode 100644 index 0000000..a51dd10 --- /dev/null +++ b/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx @@ -0,0 +1,208 @@ +import { useState } from "react"; +import { + Box, + TextField, + MenuItem, + Button, + Drawer, + FormControl, + Select, + Typography, + Stack, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; +import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import SearchIcon from "@mui/icons-material/Search"; +import RefreshIcon from "@mui/icons-material/Refresh"; + +const currencies = ["USD", "EUR", "GBP"]; +const states = ["Pending", "Completed", "Failed"]; +const transactionTypes = ["Credit", "Debit"]; +const paymentMethods = ["Card", "Bank Transfer"]; + +export default function AdvancedSearch({setForm, form, resetForm}) { + const [open, setOpen] = useState(false); + + const handleChange = (field: string, value: any) => { + setForm((prev) => ({ ...prev, [field]: value })); + }; + + const toggleDrawer = + (open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => { + if ( + event.type === "keydown" && + ((event as React.KeyboardEvent).key === "Tab" || + (event as React.KeyboardEvent).key === "Shift") + ) { + return; + } + + setOpen(open); + }; + + const list = () => ( + + + + + + Search + + {/* Buttons */} + + + + + + + {[ + { label: "Keyword", field: "keyword", type: "text" }, + { label: "Transaction ID", field: "transactionID", type: "text" }, + { + label: "Transaction Reference ID", + field: "transactionReferenceId", + type: "text", + }, + { label: "User", field: "user", type: "text" }, + { + label: "Currency", + field: "currency", + type: "select", + options: currencies, + }, + { + label: "State", + field: "state", + type: "select", + options: states, + }, + { + label: "Status Description", + field: "statusDescription", + type: "text", + }, + { + label: "Transaction Type", + field: "transactionType", + type: "select", + options: transactionTypes, + }, + { + label: "Payment Method", + field: "paymentMethod", + type: "select", + options: paymentMethods, + }, + { label: "PSPs", field: "psps", type: "text" }, + { label: "Initial PSPs", field: "initialPsps", type: "text" }, + { label: "Merchants", field: "merchants", type: "text" }, + { label: "Start Date", field: "startDate", type: "date" }, + { label: "End Date", field: "endDate", type: "date" }, + { + label: "Last Updated From", + field: "lastUpdatedFrom", + type: "date", + }, + { + label: "Last Updated To", + field: "lastUpdatedTo", + type: "date", + }, + { label: "Min Amount", field: "minAmount", type: "text" }, + { label: "Max Amount", field: "maxAmount", type: "text" }, + { label: "Channel", field: "channel", type: "text" }, + ].map(({ label, field, type, options }) => ( + + + {label} + + {type === "text" && ( + handleChange(field, e.target.value)} + /> + )} + {type === "select" && ( + + + + )} + {type === "date" && ( + handleChange(field, newValue)} + renderInput={(params) => ( + + )} + /> + )} + + ))} + + + + + ); + return ( + + + {/* */} + + {list()} + + + ); +} diff --git a/payment-iq/app/features/AdvancedSearch/store/advancedSearchSlice.ts b/payment-iq/app/features/AdvancedSearch/store/advancedSearchSlice.ts new file mode 100644 index 0000000..43b055c --- /dev/null +++ b/payment-iq/app/features/AdvancedSearch/store/advancedSearchSlice.ts @@ -0,0 +1,56 @@ +import { createSlice } from '@reduxjs/toolkit'; + +interface AdvancedSearchState { + keyword: string, + transactionID: string, + transactionReferenceId: string, + user: string, + currency: string, + state: string, + statusDescription: string, + transactionType: string, + paymentMethod: string, + psps: string, + initialPsps: string, + merchants: string, + startDate: null | string, + endDate: null | string, + lastUpdatedFrom: null | string, + lastUpdatedTo: null | string, + minAmount: string, + maxAmount: string, + channel: string, +} + +const initialState: AdvancedSearchState = { + keyword: "", + transactionID: "", + transactionReferenceId: "", + user: "", + currency: "", + state: "", + statusDescription: "", + transactionType: "", + paymentMethod: "", + psps: "", + initialPsps: "", + merchants: "", + startDate: null, + endDate: null, + lastUpdatedFrom: null, + lastUpdatedTo: null, + minAmount: "", + maxAmount: "", + channel: "", +}; + +const advancedSearchSlice = createSlice({ + name: 'advancedSearch', + initialState, + reducers: { + }, +}, +); + +export default advancedSearchSlice.reducer; + diff --git a/payment-iq/app/features/Pages/transactions/Transactions.tsx b/payment-iq/app/features/Pages/transactions/Transactions.tsx index 58f7deb..a8629c5 100644 --- a/payment-iq/app/features/Pages/transactions/Transactions.tsx +++ b/payment-iq/app/features/Pages/transactions/Transactions.tsx @@ -1,5 +1,5 @@ "use client"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Button, Dialog, @@ -22,6 +22,7 @@ import { saveAs } from "file-saver"; import { DataGrid } from "@mui/x-data-grid"; import { columns } from "./constants"; import { rows } from "./mockData"; +import AdvancedSearch from "../../AdvancedSearch/AdvancedSearch"; const paginationModel = { page: 0, pageSize: 50 }; @@ -29,6 +30,96 @@ export default function TransactionTable() { const [open, setOpen] = useState(false); const [fileType, setFileType] = useState<"csv" | "xls" | "xlsx">("csv"); const [onlyCurrentTable, setOnlyCurrentTable] = useState(false); + const [filteredRows, setFilteredRows] = useState([]) + + const [form, setForm] = useState({ + keyword: "", + transactionID: "", + transactionReferenceId: "", + user: "", + currency: "", + state: "", + statusDescription: "", + transactionType: "", + paymentMethod: "", + psps: "", + initialPsps: "", + merchants: "", + startDate: null, + endDate: null, + lastUpdatedFrom: null, + lastUpdatedTo: null, + minAmount: "", + maxAmount: "", + channel: "", + }); + + const resetForm = () => { + setForm({ + keyword: "", + transactionID: "", + transactionReferenceId: "", + user: "", + currency: "", + state: "", + statusDescription: "", + transactionType: "", + paymentMethod: "", + psps: "", + initialPsps: "", + merchants: "", + startDate: null, + endDate: null, + lastUpdatedFrom: null, + lastUpdatedTo: null, + minAmount: "", + maxAmount: "", + channel: "", + }); + }; + + + const filterRows = (rows1, filters) => { + // debugger + return rows1.filter(row => { + const hasTransactionIdFilter = filters.transactionID !== ""; + const hasStateFilter = filters.state !== ""; + + + if (hasTransactionIdFilter && hasStateFilter) { + console.log(1234) + // Return rows that match BOTH filters + return row.transactionID == filters.transactionID && row.state.toLowerCase() === filters.state.toLowerCase(); + } else if (hasTransactionIdFilter) { + console.log(12345) + // Return rows that match merchandId only + return row.transactionID == filters.transactionID; + } else if (hasStateFilter) { + // Return rows that match state only + console.log(123456) + return row.state.toLowerCase() === filters.state.toLowerCase(); + } else { + console.log(1234567) + // No filters applied, return all rows + return rows; + } + }); + }; + + + useEffect(() => { + console.log(form) + console.log(filterRows(rows, { transactionID: form.transactionID, state: form.state })) + setFilteredRows(filterRows(rows, { transactionID: form.transactionID, state: form.state })); + }, [form]) + + // useEffect(()=>{ + // if(form?.transactionId){ + // setFilteredRows(rows.filter(row => (row.merchandId.toString() === form.transactionId) && (row.state !== "" && (row.state === form.state)))); + // } else{ + // setFilteredRows(rows) + // } + // },[form]) const handleExport = () => { const exportRows = onlyCurrentTable ? rows.slice(0, 5) : rows; @@ -71,6 +162,9 @@ export default function TransactionTable() { onChange={(e) => console.log(`setSearchQuery(${e.target.value})`)} sx={{ width: 300 }} /> + + {/* */} + {/* */} +

{loginStatus}

+ + + ); +} diff --git a/payment-iq/app/testWithParams/page.tsx b/payment-iq/app/testWithParams/page.tsx new file mode 100644 index 0000000..71f1def --- /dev/null +++ b/payment-iq/app/testWithParams/page.tsx @@ -0,0 +1,97 @@ +// app/products/page.tsx +'use client'; + +import { useState } from 'react'; + +export default function ProductsPage() { + const [category, setCategory] = useState(''); + const [sort, setSort] = useState('price'); + const [limit, setLimit] = useState('10'); + const [products, setProducts] = useState([]); + const [loading, setLoading] = useState(false); + + const fetchProducts = async () => { + setLoading(true); + try { + // Construct URL with query parameters + const url = new URL('https://api.example.com/products'); + if (category) url.searchParams.append('category', category); + if (sort) url.searchParams.append('sort', sort); + if (limit) url.searchParams.append('limit', limit); + + const response = await fetch(url.toString()); + const data = await response.json(); + setProducts(data.products); + } catch (error) { + console.error('Error fetching products:', error); + } finally { + setLoading(false); + } + }; + + return ( +
+

Product Search

+ +
+
+ + setCategory(e.target.value)} + className="border p-2 rounded" + placeholder="electronics, clothing, etc." + /> +
+ +
+ + +
+ +
+ + setLimit(e.target.value)} + className="border p-2 rounded" + min="1" + max="100" + /> +
+ + +
+ + {products.length > 0 && ( +
+

Results

+
+ {products.map((product) => ( +
+

{product.name}

+

Category: {product.category}

+

Price: ${product.price}

+
+ ))} +
+
+ )} +
+ ); +} diff --git a/payment-iq/lib/store.ts b/payment-iq/lib/store.ts new file mode 100644 index 0000000..812f9b7 --- /dev/null +++ b/payment-iq/lib/store.ts @@ -0,0 +1,12 @@ +import { configureStore } from '@reduxjs/toolkit'; +import advancedSearchReducer from '@/app/features/AdvancedSearch/store/advancedSearchSlice'; + +export const store = configureStore({ + reducer: { + advancedSearch: advancedSearchReducer, + }, +}); + +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; + diff --git a/payment-iq/mock/browser.ts b/payment-iq/mock/browser.ts index 975f2cd..2845183 100644 --- a/payment-iq/mock/browser.ts +++ b/payment-iq/mock/browser.ts @@ -1,5 +1,9 @@ -// mocks/browser.ts -import { setupWorker } from "msw/browser"; -import { handlers } from "./handlers"; +// // mocks/browser.ts import { setupWorker } from "msw/browser"; +// import { handlers } from "./handlers"; +// +// export const worker = setupWorker(...handlers); + +import { setupWorker } from 'msw/browser'; +import { handlers } from './handlers'; export const worker = setupWorker(...handlers); diff --git a/payment-iq/mock/handlers.ts b/payment-iq/mock/handlers.ts index 6db727a..902d618 100644 --- a/payment-iq/mock/handlers.ts +++ b/payment-iq/mock/handlers.ts @@ -1,96 +1,98 @@ -import { http, HttpResponse } from "msw"; +// import { http, HttpResponse } from "msw"; +// +// export const handlers = [ +// http.get( +// "https://test-bo.paymentiq.io/paymentiq/backoffice/api/v2/metrics/txsummary", +// (req, _res, _ctx) => { +// const merchantId = req.url.searchParams.get("merchantId"); +// const fromDate = req.url.searchParams.get("fromDate"); +// const toDate = req.url.searchParams.get("toDate"); +// +// console.log(merchantId, fromDate, toDate); +// +// return HttpResponse.json({ +// result: { +// txCount: { total: 0, successful: 0 }, +// amount: { value: "0", currency: "EUR" }, +// }, +// }); +// } +// ), +// ]; + + +import { http, HttpResponse } from 'msw'; export const handlers = [ - http.get( - "https://test-bo.paymentiq.io/paymentiq/backoffice/api/v2/metrics/txsummary", - (req, _res, _ctx) => { - const merchantId = req.url.searchParams.get("merchantId"); - const fromDate = req.url.searchParams.get("fromDate"); - const toDate = req.url.searchParams.get("toDate"); + // Simple GET endpoint + http.get('https://api.example.com/user', () => { + return HttpResponse.json({ + id: 'usr_123', + name: 'John Doe', + email: 'john@example.com' + }); + }), - console.log(merchantId, fromDate, toDate); + // POST endpoint with request validation + http.post('https://api.example.com/login', async ({ request }) => { + const { username, password } = await request.json() as { username: string; password: string }; + if (username === 'admin' && password === 'password123') { return HttpResponse.json({ - result: { - txCount: { total: 0, successful: 0 }, - amount: { value: "0", currency: "EUR" }, - }, + token: 'mock-jwt-token', + user: { id: 'usr_123', name: 'Admin User' } }); } - ), - http.get( - "https://test-bo.paymentiq.io/paymentiq/backoffice/api/v2/users/", - (req, _res, _ctx) => { - // Mock data for merchantId = 100987998 - if (true) { - return HttpResponse.json({ - result: [ - { - merchantId: 100987998, - id: "bc6a8a55-13bc-4538-8255-cd0cec3bb4e9", - username: "lspaddy", - firstName: "Paddy", - lastName: "Man", - email: "patrick@omegasys.eu", - phone: "", - jobTitle: "", - enabled: true, - authorities: [ - "ROLE_IIN", - "ROLE_FIRST_APPROVER", - "ROLE_RULES_ADMIN", - "ROLE_TRANSACTION_VIEWER", - "ROLE_IIN_ADMIN", - "ROLE_USER_PSP_ACCOUNT", - ], - allowedMerchantIds: [100987998], - created: "2025-05-04T15:32:48.432Z", - disabledBy: null, - disabledDate: null, - disabledReason: null, - incidentNotes: false, - lastLogin: "", - lastMandatoryUpdated: "2025-05-04T15:32:48.332Z", - marketingNewsletter: false, - releaseNotes: false, - requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"], - twoFactorCondition: "required", - twoFactorCredentials: [], - }, - { - merchantId: 100987998, - id: "382eed15-1e21-41fa-b1f3-0c1adb3af714", - username: "lsterence", - firstName: "Terence", - lastName: "User", - email: "terence@omegasys.eu", - phone: "", - jobTitle: "", - enabled: true, - authorities: [ - "ROLE_IIN", - "ROLE_FIRST_APPROVER", - "ROLE_RULES_ADMIN", - ], - allowedMerchantIds: [100987998], - created: "2025-05-04T15:32:48.432Z", - disabledBy: null, - disabledDate: null, - disabledReason: null, - incidentNotes: false, - lastLogin: "", - lastMandatoryUpdated: "2025-05-04T15:32:48.332Z", - marketingNewsletter: false, - releaseNotes: false, - requiredActions: ["CONFIGURE_TOTP", "UPDATE_PASSWORD"], - twoFactorCondition: "required", - twoFactorCredentials: [], - }, - // Add more users if needed - ], - total: 4, - }); - } + + return HttpResponse.json( + { error: 'Invalid credentials' }, + { status: 401 } + ); + }), + + + // Example with query parameters + http.get('https://api.example.com/products', ({ request }) => { + // Parse the URL to access query parameters + const url = new URL(request.url); + + // Get query parameters + const category = url.searchParams.get('category'); + const sort = url.searchParams.get('sort') || 'price'; + const page = url.searchParams.get('page') || '1'; + const limit = url.searchParams.get('limit') || '10'; + + // Validate parameters + if (limit && parseInt(limit) > 100) { + return HttpResponse.json( + { error: 'Limit cannot exceed 100' }, + { status: 400 } + ); } - ), + + // Generate mock response based on parameters + const mockProducts = Array.from({ length: parseInt(limit) }, (_, i) => ({ + id: i + 1, + name: `Product ${i + 1}${category ? ` in ${category}` : ''}`, + price: Math.floor(Math.random() * 100), + category: category || 'general', + })); + + console.log(1234, mockProducts) + + // Sort products if sort parameter provided + if (sort === 'price') { + mockProducts.sort((a, b) => a.price - b.price); + } else if (sort === 'name') { + mockProducts.sort((a, b) => a.name.localeCompare(b.name)); + } + + return HttpResponse.json({ + products: mockProducts, + page: parseInt(page), + totalPages: 5, + itemsPerPage: parseInt(limit), + sortBy: sort, + }); + }), ]; diff --git a/payment-iq/mock/server.ts b/payment-iq/mock/server.ts new file mode 100644 index 0000000..719bd8c --- /dev/null +++ b/payment-iq/mock/server.ts @@ -0,0 +1,5 @@ +// mocks/server.ts +import { setupServer } from 'msw/node'; +import { handlers } from './handlers'; + +export const server = setupServer(...handlers); diff --git a/payment-iq/next.config.ts b/payment-iq/next.config.ts index e9ffa30..b9172f5 100644 --- a/payment-iq/next.config.ts +++ b/payment-iq/next.config.ts @@ -2,6 +2,12 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { /* config options here */ + webpack: (config) => { + if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') { + config.resolve.alias['@mswjs/interceptors'] = false; + } + return config; + }, }; export default nextConfig; diff --git a/payment-iq/package.json b/payment-iq/package.json index d3f094a..c37bf54 100644 --- a/payment-iq/package.json +++ b/payment-iq/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { + "msw-init": "msw init public/ --save", "dev": "next dev --turbopack", "build": "next build", "start": "next start", @@ -15,6 +16,7 @@ "@mui/material": "^7.1.2", "@mui/x-data-grid": "^8.5.2", "@mui/x-date-pickers": "^8.5.3", + "@reduxjs/toolkit": "^2.8.2", "clsx": "^2.1.1", "date-fns": "^4.1.0", "dayjs": "^1.11.13", @@ -23,6 +25,7 @@ "react": "^19.0.0", "react-date-range": "^2.0.1", "react-dom": "^19.0.0", + "react-redux": "^9.2.0", "recharts": "^2.15.3", "sass": "^1.89.2", "xlsx": "^0.18.5" @@ -34,6 +37,7 @@ "@types/react": "^19", "@types/react-date-range": "^1.4.10", "@types/react-dom": "^19", + "@types/react-redux": "^7.1.34", "eslint": "^9", "eslint-config-next": "15.3.3", "msw": "^2.10.2", @@ -44,4 +48,4 @@ "public" ] } -} \ No newline at end of file +} diff --git a/payment-iq/yarn.lock b/payment-iq/yarn.lock index cc739b9..2400af5 100644 --- a/payment-iq/yarn.lock +++ b/payment-iq/yarn.lock @@ -47,7 +47,7 @@ dependencies: "@babel/types" "^7.27.3" -"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.27.1", "@babel/runtime@^7.27.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.27.1", "@babel/runtime@^7.27.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.27.6" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz" integrity sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q== @@ -850,6 +850,18 @@ resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== +"@reduxjs/toolkit@^2.8.2": + version "2.8.2" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-2.8.2.tgz#f4e9f973c6fc930c1e0f3bf462cc95210c28f5f9" + integrity sha512-MYlOhQ0sLdw4ud48FoC5w0dH9VfWQjtCjreKwYTT3l+r427qYC5Y8PihNutepr8XrNaBUDQo9khWUwQxZaqt5A== + dependencies: + "@standard-schema/spec" "^1.0.0" + "@standard-schema/utils" "^0.3.0" + immer "^10.0.3" + redux "^5.0.1" + redux-thunk "^3.1.0" + reselect "^5.1.0" + "@rtsao/scc@^1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz" @@ -860,6 +872,16 @@ resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.11.0.tgz" integrity sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ== +"@standard-schema/spec@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c" + integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA== + +"@standard-schema/utils@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@standard-schema/utils/-/utils-0.3.0.tgz#3d5e608f16c2390c10528e98e59aef6bf73cae7b" + integrity sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g== + "@swc/counter@0.1.3": version "0.1.3" resolved "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz" @@ -945,6 +967,14 @@ resolved "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz" integrity sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A== +"@types/hoist-non-react-statics@^3.3.0": + version "3.3.6" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz#6bba74383cdab98e8db4e20ce5b4a6b98caed010" + integrity sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + "@types/json-schema@^7.0.15": version "7.0.15" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" @@ -985,6 +1015,16 @@ resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz" integrity sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw== +"@types/react-redux@^7.1.34": + version "7.1.34" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.34.tgz#83613e1957c481521e6776beeac4fd506d11bd0e" + integrity sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + "@types/react-transition-group@^4.4.12": version "4.4.12" resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz" @@ -1007,6 +1047,11 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== +"@types/use-sync-external-store@^0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz#60be8d21baab8c305132eb9cb912ed497852aadc" + integrity sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg== + "@typescript-eslint/eslint-plugin@^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0": version "8.34.1" resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.1.tgz" @@ -2420,7 +2465,7 @@ headers-polyfill@^4.0.2: resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-4.0.3.tgz#922a0155de30ecc1f785bcf04be77844ca95ad07" integrity sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ== -hoist-non-react-statics@^3.3.1: +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1: version "3.3.2" resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -2437,6 +2482,11 @@ ignore@^7.0.0: resolved "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz" integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== +immer@^10.0.3: + version "10.1.1" + resolved "https://registry.yarnpkg.com/immer/-/immer-10.1.1.tgz#206f344ea372d8ea176891545ee53ccc062db7bc" + integrity sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw== + immutable@^5.0.2: version "5.1.3" resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.3.tgz#e6486694c8b76c37c063cca92399fa64098634d4" @@ -3174,6 +3224,14 @@ react-list@^0.8.13: resolved "https://registry.npmjs.org/react-list/-/react-list-0.8.18.tgz" integrity sha512-1OSdDvzuKuwDJvQNuhXxxL+jTmmdtKg1i6KtYgxI9XR98kbOql1FcSGP+Lcvo91fk3cYng+Z6YkC6X9HRJwxfw== +react-redux@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-9.2.0.tgz#96c3ab23fb9a3af2cb4654be4b51c989e32366f5" + integrity sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g== + dependencies: + "@types/use-sync-external-store" "^0.0.6" + use-sync-external-store "^1.4.0" + react-smooth@^4.0.4: version "4.0.4" resolved "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz" @@ -3224,6 +3282,23 @@ recharts@^2.15.3: tiny-invariant "^1.3.1" victory-vendor "^36.6.8" +redux-thunk@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-3.1.0.tgz#94aa6e04977c30e14e892eae84978c1af6058ff3" + integrity sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw== + +redux@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197" + integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== + dependencies: + "@babel/runtime" "^7.9.2" + +redux@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-5.0.1.tgz#97fa26881ce5746500125585d5642c77b6e9447b" + integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w== + reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9: version "1.0.10" resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz" @@ -3260,7 +3335,7 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== -reselect@^5.1.1: +reselect@^5.1.0, reselect@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz" integrity sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w== @@ -3832,7 +3907,7 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" -use-sync-external-store@^1.5.0: +use-sync-external-store@^1.4.0, use-sync-external-store@^1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz" integrity sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==