diff --git a/package.json b/package.json index 168986b..02c8cde 100644 --- a/package.json +++ b/package.json @@ -44,13 +44,12 @@ "devDependencies": { "@chromatic-com/storybook": "^4.1.3", "@eslint/js": "^9.33.0", - "@storybook/addon-a11y": "^10.1.4", - "@storybook/addon-docs": "^10.1.4", - "@storybook/addon-onboarding": "^10.1.4", - "@storybook/addon-vitest": "^10.1.4", + "@storybook/addon-a11y": "^10.1.10", + "@storybook/addon-docs": "^10.1.10", + "@storybook/addon-onboarding": "^10.1.10", + "@storybook/addon-vitest": "^10.1.10", "@storybook/experimental-addon-test": "^8.6.14", - "@storybook/react": "^10.1.4", - "@storybook/react-vite": "^10.1.4", + "@storybook/react-vite": "^10.1.10", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.0", @@ -66,13 +65,13 @@ "eslint": "^9.33.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", - "eslint-plugin-storybook": "^10.1.4", + "eslint-plugin-storybook": "^10.1.10", "globals": "^16.3.0", "jsdom": "^27.2.0", "knip": "^5.73.1", "playwright": "^1.57.0", "postcss": "^8.5.6", - "storybook": "^10.1.4", + "storybook": "^10.1.10", "tailwindcss": "^3.4.4", "typescript": "~5.8.3", "typescript-eslint": "^8.39.1", @@ -87,4 +86,4 @@ } }, "packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39" -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7871c7b..71749a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -69,31 +69,28 @@ importers: devDependencies: '@chromatic-com/storybook': specifier: ^4.1.3 - version: 4.1.3(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + version: 4.1.3(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) '@eslint/js': specifier: ^9.33.0 version: 9.39.2 '@storybook/addon-a11y': - specifier: ^10.1.4 - version: 10.1.9(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + specifier: ^10.1.10 + version: 10.1.10(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) '@storybook/addon-docs': - specifier: ^10.1.4 - version: 10.1.9(@types/react@19.2.7)(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) + specifier: ^10.1.10 + version: 10.1.10(@types/react@19.2.7)(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) '@storybook/addon-onboarding': - specifier: ^10.1.4 - version: 10.1.9(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + specifier: ^10.1.10 + version: 10.1.10(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) '@storybook/addon-vitest': - specifier: ^10.1.4 - version: 10.1.9(@vitest/browser-playwright@4.0.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vitest@4.0.16) + specifier: ^10.1.10 + version: 10.1.10(@vitest/browser-playwright@4.0.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vitest@4.0.16) '@storybook/experimental-addon-test': specifier: ^8.6.14 - version: 8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vitest@4.0.16) - '@storybook/react': - specifier: ^10.1.4 - version: 10.1.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3) + version: 8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vitest@4.0.16) '@storybook/react-vite': - specifier: ^10.1.4 - version: 10.1.9(esbuild@0.27.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.53.5)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) + specifier: ^10.1.10 + version: 10.1.10(esbuild@0.27.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.53.5)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) '@testing-library/dom': specifier: ^10.4.1 version: 10.4.1 @@ -140,8 +137,8 @@ importers: specifier: ^0.4.20 version: 0.4.25(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-storybook: - specifier: ^10.1.4 - version: 10.1.9(eslint@9.39.2(jiti@1.21.7))(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3) + specifier: ^10.1.10 + version: 10.1.10(eslint@9.39.2(jiti@1.21.7))(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3) globals: specifier: ^16.3.0 version: 16.5.0 @@ -158,8 +155,8 @@ importers: specifier: ^8.5.6 version: 8.5.6 storybook: - specifier: ^10.1.4 - version: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^10.1.10 + version: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) tailwindcss: specifier: ^3.4.4 version: 3.4.19 @@ -937,28 +934,28 @@ packages: '@standard-schema/utils@0.3.0': resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} - '@storybook/addon-a11y@10.1.9': - resolution: {integrity: sha512-MJjJQY9liDyOi7PIE9c0hfa+2jNCdRskRwoR8G3Klli0FIhXjxlAci6BjCGX9W3deOuwvDT13xwVg5YG6Mi13A==} + '@storybook/addon-a11y@10.1.10': + resolution: {integrity: sha512-lXVFywCSdA39uCR0KEFz3F6WTjzoqSi5gQYtWrFelzaUiMH46uBLHPYaKlpUuNbTL/o9ctrhX1YNzegujrXSoQ==} peerDependencies: - storybook: ^10.1.9 + storybook: ^10.1.10 - '@storybook/addon-docs@10.1.9': - resolution: {integrity: sha512-SvwEZ32lyk5p3PRmE3pmfAhs4HMiVo5zxjTBVmK9kgz9zGgWCTlikb56tJ998hVe52CFyCvt3I9rkHeYMCKPww==} + '@storybook/addon-docs@10.1.10': + resolution: {integrity: sha512-PSJVtawnGNrEkeLJQn9TTdeqrtDij8onvmnFtfkDaFG5IaUdQaLX9ibJ4gfxYakq+BEtlCcYiWErNJcqDrDluQ==} peerDependencies: - storybook: ^10.1.9 + storybook: ^10.1.10 - '@storybook/addon-onboarding@10.1.9': - resolution: {integrity: sha512-9f0F5DBA01jZSZXrOzhiuubMdQrej8C15mrIcXoPFNPNbvx9IBYsAiVWv3Tj76mF1IuvVy0J7vzNtGT+kMvKzg==} + '@storybook/addon-onboarding@10.1.10': + resolution: {integrity: sha512-CtfoHqgdm63NsGyYBcr1UhJV6m213ckU3aKTYJRS+3NLkx18BIME9biJwiTiRK4Pm4jbc69V21JzLumFcaiJbw==} peerDependencies: - storybook: ^10.1.9 + storybook: ^10.1.10 - '@storybook/addon-vitest@10.1.9': - resolution: {integrity: sha512-rIJEwWhhguleQ8Sw0rI3artubm+PzgHqS5nG00KpWnGp4mvsx0k3kxJjSyf9VhSApyG9G3SMB+05JBlGbJGKdA==} + '@storybook/addon-vitest@10.1.10': + resolution: {integrity: sha512-dh5ZesgvZY619nkweo9fbORQQSU0hIFQnqlcnU1DrGXumt9SzVHF3/2Lxe+HGHLHK6Sk8jZp/16BjZ/zxSG61Q==} peerDependencies: '@vitest/browser': ^3.0.0 || ^4.0.0 '@vitest/browser-playwright': ^4.0.0 '@vitest/runner': ^3.0.0 || ^4.0.0 - storybook: ^10.1.9 + storybook: ^10.1.10 vitest: ^3.0.0 || ^4.0.0 peerDependenciesMeta: '@vitest/browser': @@ -970,18 +967,18 @@ packages: vitest: optional: true - '@storybook/builder-vite@10.1.9': - resolution: {integrity: sha512-rUILpjGV7gKfXrUeZzpNAer9PspB3LJI1d+gJHISx2Gs24bdneA3y/gu0fWw46ccOSIcwb91xoK5QxliJcWsWg==} + '@storybook/builder-vite@10.1.10': + resolution: {integrity: sha512-6m6zOyDhHLynv3lvkH70s1YoIkIFPhbpGsBKvHchRLrZLe8hCPeafIFLfZRPoD4yIPwBS6rWbjMsSvBMFlR+ag==} peerDependencies: - storybook: ^10.1.9 + storybook: ^10.1.10 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - '@storybook/csf-plugin@10.1.9': - resolution: {integrity: sha512-17LXUqpbVvsMt7KJwgr0bPUX+uEGArc6EOi+DC5X/CQ+i0nXxxLMpDHdTyrsdKxCZIT087OpSNbTEWP5ACEAlA==} + '@storybook/csf-plugin@10.1.10': + resolution: {integrity: sha512-2dri4TRU8uuj/skmx/ZBw+GnnXf8EZHiMDMeijVRdBQtYFWPeoYzNIrGRpNfbuGpnDP0dcxrqti/TsedoxwFkA==} peerDependencies: esbuild: '*' rollup: '*' - storybook: ^10.1.9 + storybook: ^10.1.10 vite: '*' webpack: '*' peerDependenciesMeta: @@ -1030,27 +1027,27 @@ packages: peerDependencies: storybook: ^8.6.14 - '@storybook/react-dom-shim@10.1.9': - resolution: {integrity: sha512-gJsR6fI1gG4DSin6sQx8RmGDQF8Lije0cZbxHyVedNleBsveGXIPFUKFVi+pRNdwBPni1Z2g/gYyHzkOEqPD2w==} + '@storybook/react-dom-shim@10.1.10': + resolution: {integrity: sha512-9pmUbEr1MeMHg9TG0c2jVUfHWr2AA86vqZGphY/nT6mbe/rGyWtBl5EnFLrz6WpI8mo3h+Kxs6p2oiuIYieRtw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.1.9 + storybook: ^10.1.10 - '@storybook/react-vite@10.1.9': - resolution: {integrity: sha512-2f2mLGTDKYzIFi5Xnu5TEBpnDXazSAKMliVsUKrCr+gunfk8uPApj0njATvZoRB3xTZ44Aacf7l9EZQaTYxB/Q==} + '@storybook/react-vite@10.1.10': + resolution: {integrity: sha512-6kE4/88YuwO07P0DR6caKNDNvCB/VnpimPmj4Jv6qmqrBgnoOOiXHIKyHJD+EjNyrbbwv4ygG01RVEajpjQaDA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.1.9 + storybook: ^10.1.10 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - '@storybook/react@10.1.9': - resolution: {integrity: sha512-NqiFp5rJmxzs0teNAGqgGH0nD8q1aYR8AxQl9OYSHULYoLJR1/RqcyBPTTBjxAOpWF/pZgLBrRW+FjZbjKLLMQ==} + '@storybook/react@10.1.10': + resolution: {integrity: sha512-9Rpr8/wX0p5/EaulrxpqrjKjhGaA/Ab9HgxzTqs2Shz0gvMAQHoiRnTEp7RCCkP49ruFYnIp0yGRSovu03LakQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.1.9 + storybook: ^10.1.10 typescript: '>= 4.9.x' peerDependenciesMeta: typescript: @@ -2082,11 +2079,11 @@ packages: peerDependencies: eslint: '>=8.40' - eslint-plugin-storybook@10.1.9: - resolution: {integrity: sha512-2XCnHhu+9ShW8U/MsvnlT4ZkzADIPtlfYVD/GBBbs8loWu0x9IZ3EfNg1LEImjvvNVDhwpd5K04lK4CAP+2bWA==} + eslint-plugin-storybook@10.1.10: + resolution: {integrity: sha512-ITr6Aq3buR/DuDATkq1BafUVJLybyo676fY+tj9Zjd1Ak+UXBAMQcQ++tiBVVHm1RqADwM3b1o6bnWHK2fPPKw==} peerDependencies: eslint: '>=8' - storybook: ^10.1.9 + storybook: ^10.1.10 eslint-scope@8.4.0: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} @@ -3580,8 +3577,8 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - storybook@10.1.9: - resolution: {integrity: sha512-gHW/jOxLNzVw/Ys1XJovgrMFyh37ftMsLIw0l0h4fLsEyXhUABwrgjDp5bWrUmbQqemAIYVAAtw7UjPEdcHgkA==} + storybook@10.1.10: + resolution: {integrity: sha512-oK0t0jEogiKKfv5Z1ao4Of99+xWw1TMUGuGRYDQS4kp2yyBsJQEgu7NI7OLYsCDI6gzt5p3RPtl1lqdeVLUi8A==} hasBin: true peerDependencies: prettier: ^2 || ^3 @@ -4393,13 +4390,13 @@ snapshots: - sugar-high - supports-color - '@chromatic-com/storybook@4.1.3(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + '@chromatic-com/storybook@4.1.3(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: '@neoconfetti/react': 1.0.0 chromatic: 13.3.4 filesize: 10.1.6 jsonfile: 6.2.0 - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) strip-ansi: 7.1.2 transitivePeerDependencies: - '@chromatic-com/cypress' @@ -4897,21 +4894,21 @@ snapshots: '@standard-schema/utils@0.3.0': {} - '@storybook/addon-a11y@10.1.9(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + '@storybook/addon-a11y@10.1.10(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: '@storybook/global': 5.0.0 axe-core: 4.11.0 - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@storybook/addon-docs@10.1.9(@types/react@19.2.7)(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7))': + '@storybook/addon-docs@10.1.10(@types/react@19.2.7)(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.7)(react@19.2.3) - '@storybook/csf-plugin': 10.1.9(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) + '@storybook/csf-plugin': 10.1.10(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) '@storybook/icons': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@storybook/react-dom-shim': 10.1.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/react-dom-shim': 10.1.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' @@ -4920,15 +4917,15 @@ snapshots: - vite - webpack - '@storybook/addon-onboarding@10.1.9(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + '@storybook/addon-onboarding@10.1.10(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@storybook/addon-vitest@10.1.9(@vitest/browser-playwright@4.0.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vitest@4.0.16)': + '@storybook/addon-vitest@10.1.10(@vitest/browser-playwright@4.0.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vitest@4.0.16)': dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) optionalDependencies: '@vitest/browser-playwright': 4.0.16(playwright@1.57.0)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7))(vitest@4.0.16) vitest: 4.0.16(@types/node@25.0.3)(@vitest/browser-playwright@4.0.16)(jiti@1.21.7)(jsdom@27.3.0(postcss@8.5.6)) @@ -4936,11 +4933,11 @@ snapshots: - react - react-dom - '@storybook/builder-vite@10.1.9(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7))': + '@storybook/builder-vite@10.1.10(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7))': dependencies: - '@storybook/csf-plugin': 10.1.9(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) + '@storybook/csf-plugin': 10.1.10(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) '@vitest/mocker': 3.2.4(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) ts-dedent: 2.2.0 vite: 7.3.0(@types/node@25.0.3)(jiti@1.21.7) transitivePeerDependencies: @@ -4949,24 +4946,24 @@ snapshots: - rollup - webpack - '@storybook/csf-plugin@10.1.9(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7))': + '@storybook/csf-plugin@10.1.10(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7))': dependencies: - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) unplugin: 2.3.11 optionalDependencies: esbuild: 0.27.1 rollup: 4.53.5 vite: 7.3.0(@types/node@25.0.3)(jiti@1.21.7) - '@storybook/experimental-addon-test@8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vitest@4.0.16)': + '@storybook/experimental-addon-test@8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vitest@4.0.16)': dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 1.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@storybook/instrumenter': 8.6.14(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/test': 8.6.14(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/instrumenter': 8.6.14(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/test': 8.6.14(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) polished: 4.3.1 prompts: 2.4.2 - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) ts-dedent: 2.2.0 optionalDependencies: vitest: 4.0.16(@types/node@25.0.3)(@vitest/browser-playwright@4.0.16)(jiti@1.21.7)(jsdom@27.3.0(postcss@8.5.6)) @@ -4986,31 +4983,31 @@ snapshots: react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - '@storybook/instrumenter@8.6.14(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + '@storybook/instrumenter@8.6.14(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: '@storybook/global': 5.0.0 '@vitest/utils': 2.1.9 - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@storybook/react-dom-shim@10.1.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + '@storybook/react-dom-shim@10.1.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@storybook/react-vite@10.1.9(esbuild@0.27.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.53.5)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7))': + '@storybook/react-vite@10.1.10(esbuild@0.27.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.53.5)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7))': dependencies: '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.3(typescript@5.8.3)(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) '@rollup/pluginutils': 5.3.0(rollup@4.53.5) - '@storybook/builder-vite': 10.1.9(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) - '@storybook/react': 10.1.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3) + '@storybook/builder-vite': 10.1.10(esbuild@0.27.1)(rollup@4.53.5)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.0(@types/node@25.0.3)(jiti@1.21.7)) + '@storybook/react': 10.1.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3) empathic: 2.0.0 magic-string: 0.30.21 react: 19.2.3 react-docgen: 8.0.2 react-dom: 19.2.3(react@19.2.3) resolve: 1.22.11 - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) tsconfig-paths: 4.2.0 vite: 7.3.0(@types/node@25.0.3)(jiti@1.21.7) transitivePeerDependencies: @@ -5021,29 +5018,29 @@ snapshots: - typescript - webpack - '@storybook/react@10.1.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3)': + '@storybook/react@10.1.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3)': dependencies: '@storybook/global': 5.0.0 - '@storybook/react-dom-shim': 10.1.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/react-dom-shim': 10.1.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) react: 19.2.3 react-docgen: 8.0.2 react-dom: 19.2.3(react@19.2.3) - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@storybook/test@8.6.14(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + '@storybook/test@8.6.14(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: '@storybook/global': 5.0.0 - '@storybook/instrumenter': 8.6.14(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/instrumenter': 8.6.14(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) '@testing-library/dom': 10.4.0 '@testing-library/jest-dom': 6.5.0 '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) '@vitest/expect': 2.0.5 '@vitest/spy': 2.0.5 - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/query-core@5.90.12': {} @@ -6165,11 +6162,11 @@ snapshots: dependencies: eslint: 9.39.2(jiti@1.21.7) - eslint-plugin-storybook@10.1.9(eslint@9.39.2(jiti@1.21.7))(storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3): + eslint-plugin-storybook@10.1.10(eslint@9.39.2(jiti@1.21.7))(storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3): dependencies: '@typescript-eslint/utils': 8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.8.3) eslint: 9.39.2(jiti@1.21.7) - storybook: 10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) transitivePeerDependencies: - supports-color - typescript @@ -7983,7 +7980,7 @@ snapshots: std-env@3.10.0: {} - storybook@10.1.9(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + storybook@10.1.10(@testing-library/dom@10.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) diff --git a/src/api/services/course.service.ts b/src/api/services/course.service.ts index 7fce2c0..70dac91 100644 --- a/src/api/services/course.service.ts +++ b/src/api/services/course.service.ts @@ -54,7 +54,12 @@ const create = async (payload: FormData): Promise => { const update = async (courseId: string, data: FormData): Promise => { const response = await apiClient.put>( `/courses/${courseId}`, - data + data, + { + headers: { + 'Content-Type': 'multipart/form-data', + }, + } ); return response.data.data; }; diff --git a/src/components/common/Footer.tsx b/src/components/common/Footer.tsx index fff70f5..7c7af1d 100644 --- a/src/components/common/Footer.tsx +++ b/src/components/common/Footer.tsx @@ -40,10 +40,10 @@ export function Footer() {

Síguenos

- - - - + + + +
diff --git a/src/components/layouts/MainLayout.tsx b/src/components/layouts/MainLayout.tsx index f68aee9..d07a121 100644 --- a/src/components/layouts/MainLayout.tsx +++ b/src/components/layouts/MainLayout.tsx @@ -1,15 +1,12 @@ -import { Outlet, useLocation } from 'react-router-dom'; +import { Outlet } from 'react-router-dom'; import { NavBar } from '../common/NavBar'; import { Footer } from '../common/Footer.tsx'; const MainLayout = () => { - const location = useLocation(); - const isLandingPage = location.pathname === '/'; - return ( -
+
-
+
diff --git a/src/components/student/MaterialsList.tsx b/src/components/student/MaterialsList.tsx index 6ede58b..6c20fdc 100644 --- a/src/components/student/MaterialsList.tsx +++ b/src/components/student/MaterialsList.tsx @@ -84,7 +84,7 @@ export default function MaterialsList({ materials }: MaterialsListProps) {
, diff --git a/src/components/ui/StatusBadge/StatusBadge.tsx b/src/components/ui/StatusBadge/StatusBadge.tsx index 0c8c31d..1d38422 100644 --- a/src/components/ui/StatusBadge/StatusBadge.tsx +++ b/src/components/ui/StatusBadge/StatusBadge.tsx @@ -1,8 +1,15 @@ import Badge from '../Badge/Badge'; -import { Clock, CheckCircle, XCircle } from 'lucide-react'; +import { Clock, CheckCircle, XCircle, TrendingUp } from 'lucide-react'; interface StatusBadgeProps { - status: 'pending' | 'accepted' | 'rejected' | string; + status: + | 'pending' + | 'accepted' + | 'rejected' + | 'enrolled' + | 'in-progress' + | 'completed' + | string; } /** * StatusBadge Component @@ -31,9 +38,24 @@ const StatusBadge = ({ status }: StatusBadgeProps) => { Rechazado ); + case 'enrolled': + case 'in-progress': + return ( + + + En Progreso + + ); + case 'completed': + return ( + + + Completado + + ); default: return {status}; } }; -export default StatusBadge; \ No newline at end of file +export default StatusBadge; diff --git a/src/pages/AboutPage.tsx b/src/pages/AboutPage.tsx index 54a0f80..7a5dfe8 100644 --- a/src/pages/AboutPage.tsx +++ b/src/pages/AboutPage.tsx @@ -1,9 +1,14 @@ -import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/Card/Card'; +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from '../components/ui/Card/Card'; export default function AboutPage() { return ( -
-
+
+

Acerca de Nosotros

@@ -14,8 +19,10 @@ export default function AboutPage() {

- Somos una plataforma educativa dedicada a democratizar el acceso a la educación de calidad. - Nuestro objetivo es conectar a estudiantes con profesores expertos en diversas áreas del conocimiento. + Somos una plataforma educativa dedicada a democratizar el acceso a + la educación de calidad. Nuestro objetivo es conectar a + estudiantes con profesores expertos en diversas áreas del + conocimiento.

@@ -26,9 +33,9 @@ export default function AboutPage() {

- Aspiramos a ser la plataforma de aprendizaje en línea líder, donde cada persona pueda - desarrollar sus habilidades y alcanzar su máximo potencial a través de cursos accesibles - y de alta calidad. + Aspiramos a ser la plataforma de aprendizaje en línea líder, donde + cada persona pueda desarrollar sus habilidades y alcanzar su + máximo potencial a través de cursos accesibles y de alta calidad.

diff --git a/src/pages/Admin/AdminDashboard.tsx b/src/pages/Admin/AdminDashboard.tsx index 0507c8c..7ecab91 100644 --- a/src/pages/Admin/AdminDashboard.tsx +++ b/src/pages/Admin/AdminDashboard.tsx @@ -8,12 +8,7 @@ import { CardTitle, } from '../../components/ui/Card/Card'; import StatusBadge from '../../components/ui/StatusBadge/StatusBadge'; -import { - Users, - BookOpen, - GraduationCap, - DollarSign, -} from 'lucide-react'; +import { Users, BookOpen, GraduationCap, DollarSign } from 'lucide-react'; import { appealService } from '../../api/services/appeal.service'; import { useAdminAnalytics } from '../../hooks/useAdmin'; import { formatCurrency } from '../../lib/currency'; @@ -90,63 +85,64 @@ export default function AdminDashboard() { }, []); return ( -
-
-

- Dashboard de Administrador -

-

Resumen general de la plataforma.

-
- -
- {stats.map((stat) => ( - - - - {stat.title} - - - - -
- {stat.value} -
-

- {stat.change} desde el mes pasado -

-
-
- ))} -
+
+
+
+

+ Dashboard de Administrador +

+

Resumen general de la plataforma.

+
- {isLoadingAnalytics ? ( -
-

Cargando estadísticas...

+
+ {stats.map((stat) => ( + + + + {stat.title} + + + + +
+ {stat.value} +
+

+ {stat.change} desde el mes pasado +

+
+
+ ))}
- ) : null} - - - - - Solicitudes Recientes - - - Últimas solicitudes recibidas.{' '} - - Ver todas - - . - - - + {isLoadingAnalytics ? ( +
+

Cargando estadísticas...

+
+ ) : null} + + + + + + Solicitudes Recientes + + + Últimas solicitudes recibidas.{' '} + + Ver todas + + . + + +
{isLoading ? (

Cargando...

@@ -185,6 +181,7 @@ export default function AdminDashboard() {
+
); } diff --git a/src/pages/Admin/AnalyticsPage.tsx b/src/pages/Admin/AnalyticsPage.tsx index 0818d82..6d46a5a 100644 --- a/src/pages/Admin/AnalyticsPage.tsx +++ b/src/pages/Admin/AnalyticsPage.tsx @@ -95,382 +95,391 @@ export default function AnalyticsPage() { ]; return ( -
-
-

- Estadísticas y Métricas -

-

- Panel de análisis y rendimiento de la plataforma. -

-
+
+
+
+

+ Estadísticas y Métricas +

+

+ Panel de análisis y rendimiento de la plataforma. +

+
- {/* Métricas Principales */} -
- - - - Estudiantes Activos - - - - -
- {analytics.totalStudents.toLocaleString('es-AR')} -
-

= 0 - ? 'text-green-600' - : 'text-red-600' - }`} - > - {analytics.growth.studentsGrowthPercentage >= 0 ? '+' : ''} - {analytics.growth.studentsGrowthPercentage.toFixed(1)}% este mes -

-
-
+ {/* Métricas Principales */} +
+ + + + Estudiantes Activos + + + + +
+ {analytics.totalStudents.toLocaleString('es-AR')} +
+

= 0 + ? 'text-green-600' + : 'text-red-600' + }`} + > + {analytics.growth.studentsGrowthPercentage >= 0 ? '+' : ''} + {analytics.growth.studentsGrowthPercentage.toFixed(1)}% este mes +

+
+
- - - - Profesores Activos - - - - -
- {analytics.totalProfessors.toLocaleString('es-AR')} -
-

= 0 - ? 'text-green-600' - : 'text-red-600' - }`} - > - {analytics.growth.professorsGrowthPercentage >= 0 ? '+' : ''} - {analytics.growth.professorsGrowthPercentage.toFixed(1)}% este mes -

-
-
+ + + + Profesores Activos + + + + +
+ {analytics.totalProfessors.toLocaleString('es-AR')} +
+

= 0 + ? 'text-green-600' + : 'text-red-600' + }`} + > + {analytics.growth.professorsGrowthPercentage >= 0 ? '+' : ''} + {analytics.growth.professorsGrowthPercentage.toFixed(1)}% este + mes +

+
+
- - - - Cursos Totales - - - - -
- {analytics.totalCourses.toLocaleString('es-AR')} -
-

- {analytics.courseStats.byStatus.publicado} publicados -

-
-
+ + + + Cursos Totales + + + + +
+ {analytics.totalCourses.toLocaleString('es-AR')} +
+

+ {analytics.courseStats.byStatus.publicado} publicados +

+
+
- - - - Ingresos Plataforma - - - - -
- {formatCurrency(analytics.platformEarningsInCents)} -
-

= 0 - ? 'text-green-600' - : 'text-red-600' - }`} - > - {analytics.growth.revenueGrowthPercentage >= 0 ? '+' : ''} - {analytics.growth.revenueGrowthPercentage.toFixed(1)}% este mes -

-
-
-
+ + + + Ingresos Plataforma + + + + +
+ {formatCurrency(analytics.platformEarningsInCents)} +
+

= 0 + ? 'text-green-600' + : 'text-red-600' + }`} + > + {analytics.growth.revenueGrowthPercentage >= 0 ? '+' : ''} + {analytics.growth.revenueGrowthPercentage.toFixed(1)}% este mes +

+
+
+
+ + {/* Gráficos */} +
+ + + + + Crecimiento de Usuarios + + + Nuevos usuarios por mes (últimos 6 meses) + + + + + + + + + + + + + + + + + + + + + + Ingresos Mensuales + + + Evolución de ingresos (últimos 6 meses) + + + + + + + + + + `$${Number(value).toLocaleString('es-AR', { + minimumFractionDigits: 2, + })}` + } + /> + + + + + + + +
+ + {/* Estado de Cursos y Top Rankings */} +
+ + + Distribución de Cursos por Estado + + Estado actual de todos los cursos + + + + + + + `${entry.name}: ${(entry.percent * 100).toFixed(0)}%` + } + outerRadius={80} + fill="#8884d8" + dataKey="value" + > + {courseStatusData.map((entry, index) => ( + + ))} + + + + +
+
+ Cursos Gratuitos: + + {analytics.courseStats.freeCourses} + +
+
+ Cursos de Pago: + + {analytics.courseStats.paidCourses} + +
+ {analytics.courseStats.averagePriceInCents && ( +
+ Precio Promedio: + + {formatCurrency( + analytics.courseStats.averagePriceInCents + )} + +
+ )} +
+
+
+ + + + Top 5 Cursos Más Vendidos + Cursos con más ventas + + +
+ {analytics.topCourses.map((course, index) => ( +
+
+
+ + #{index + 1} + +
+
+

+ {course.courseName} +

+

+ Por {course.professorName} +

+
+
+
+

+ {course.salesCount} ventas +

+

+ {formatCurrency(course.totalEarningsInCents)} +

+
+
+ ))} +
+
+
+
- {/* Gráficos */} -
+ {/* Top Profesores */} - - Crecimiento de Usuarios + + Top 5 Profesores Más Exitosos - - Nuevos usuarios por mes (últimos 6 meses) - + Profesores con mayores ingresos - - - - - - - - - - - +
+ + + + + + + + + + + + {analytics.topProfessors.map((professor, index) => ( + + + + + + + + ))} + +
+ Posición + + Profesor + + Cursos + + Estudiantes + + Ganancias (97%) +
+
+ + #{index + 1} + +
+
+ {professor.professorName} + + {professor.coursesCount} + + {professor.totalStudents.toLocaleString('es-AR')} + + {formatCurrency(professor.totalEarningsInCents)} +
+
+ {/* Actividad Reciente */} - - - Ingresos Mensuales - + Actividad Reciente - Evolución de ingresos (últimos 6 meses) + Resumen de actividad reciente en la plataforma - - - - - - - `$${Number(value).toLocaleString('es-AR', { - minimumFractionDigits: 2, - })}` - } - /> - - - - - - - -
- - {/* Estado de Cursos y Top Rankings */} -
- - - Distribución de Cursos por Estado - Estado actual de todos los cursos - - - - - - `${entry.name}: ${(entry.percent * 100).toFixed(0)}%` - } - outerRadius={80} - fill="#8884d8" - dataKey="value" - > - {courseStatusData.map((entry, index) => ( - - ))} - - - - -
-
- Cursos Gratuitos: - - {analytics.courseStats.freeCourses} - +
+
+

+ {analytics.recentActivity.newStudentsToday} +

+

Estudiantes hoy

-
- Cursos de Pago: - - {analytics.courseStats.paidCourses} - +
+

+ {analytics.recentActivity.newProfessorsToday} +

+

Profesores hoy

+
+
+

+ {analytics.recentActivity.salesToday} +

+

Ventas hoy

+
+
+

+ {analytics.recentActivity.newCoursesThisWeek} +

+

+ Cursos esta semana +

+
+
+

+ {analytics.recentActivity.newEnrollmentsToday} +

+

Inscripciones hoy

- {analytics.courseStats.averagePriceInCents && ( -
- Precio Promedio: - - {formatCurrency(analytics.courseStats.averagePriceInCents)} - -
- )} -
- - - - - - Top 5 Cursos Más Vendidos - Cursos con más ventas - - -
- {analytics.topCourses.map((course, index) => ( -
-
-
- - #{index + 1} - -
-
-

- {course.courseName} -

-

- Por {course.professorName} -

-
-
-
-

- {course.salesCount} ventas -

-

- {formatCurrency(course.totalEarningsInCents)} -

-
-
- ))}
- - {/* Top Profesores */} - - - - - Top 5 Profesores Más Exitosos - - Profesores con mayores ingresos - - -
- - - - - - - - - - - - {analytics.topProfessors.map((professor, index) => ( - - - - - - - - ))} - -
- Posición - - Profesor - - Cursos - - Estudiantes - - Ganancias (97%) -
-
- - #{index + 1} - -
-
- {professor.professorName} - - {professor.coursesCount} - - {professor.totalStudents.toLocaleString('es-AR')} - - {formatCurrency(professor.totalEarningsInCents)} -
-
-
-
- - {/* Actividad Reciente */} - - - Actividad Reciente - - Resumen de actividad reciente en la plataforma - - - -
-
-

- {analytics.recentActivity.newStudentsToday} -

-

Estudiantes hoy

-
-
-

- {analytics.recentActivity.newProfessorsToday} -

-

Profesores hoy

-
-
-

- {analytics.recentActivity.salesToday} -

-

Ventas hoy

-
-
-

- {analytics.recentActivity.newCoursesThisWeek} -

-

Cursos esta semana

-
-
-

- {analytics.recentActivity.newEnrollmentsToday} -

-

Inscripciones hoy

-
-
-
-
); } diff --git a/src/pages/Admin/CourseTypesPage.tsx b/src/pages/Admin/CourseTypesPage.tsx index 6ea1b86..3b56e55 100644 --- a/src/pages/Admin/CourseTypesPage.tsx +++ b/src/pages/Admin/CourseTypesPage.tsx @@ -10,7 +10,11 @@ import { CardTitle, } from '../../components/ui/Card/Card'; import Button from '../../components/ui/Button/Button'; -import { Dialog, DialogHeader, DialogTitle } from '../../components/ui/Dialog/Dialog'; +import { + Dialog, + DialogHeader, + DialogTitle, +} from '../../components/ui/Dialog/Dialog'; import Input from '../../components/ui/Input/Input'; import Textarea from '../../components/ui/TextArea/TextArea'; import { Plus, Edit, Trash2, Search } from 'lucide-react'; @@ -25,7 +29,10 @@ import { useDebounce } from '../../hooks/useDebounce'; const CourseTypeSchema = v.object({ name: v.pipe(v.string(), v.minLength(1, 'El nombre es requerido.')), - description: v.pipe(v.string(), v.minLength(1, 'La descripción es requerida.')), + description: v.pipe( + v.string(), + v.minLength(1, 'La descripción es requerida.') + ), }); type CourseTypeFormData = v.InferInput; @@ -34,23 +41,32 @@ const TYPES_PER_PAGE = 5; export default function CourseTypesPage() { const [isModalOpen, setIsModalOpen] = useState(false); const [currentTypeId, setCurrentTypeId] = useState(null); - + const [searchTerm, setSearchTerm] = useState(''); const [sortOrder, setSortOrder] = useState<'ASC' | 'DESC'>('ASC'); const [currentPage, setCurrentPage] = useState(1); const debouncedSearchTerm = useDebounce(searchTerm, 500); - const { register, handleSubmit, formState: { errors }, setValue, reset } = useForm({ + const { + register, + handleSubmit, + formState: { errors }, + setValue, + reset, + } = useForm({ resolver: valibotResolver(CourseTypeSchema), }); - const filters = useMemo(() => ({ + const filters = useMemo( + () => ({ q: debouncedSearchTerm || undefined, sortBy: 'name', sortOrder, limit: TYPES_PER_PAGE, offset: (currentPage - 1) * TYPES_PER_PAGE, - }), [debouncedSearchTerm, sortOrder, currentPage]); + }), + [debouncedSearchTerm, sortOrder, currentPage] + ); const { data, isLoading, error } = useCourseTypes(filters); const createMutation = useCreateCourseType(); @@ -79,7 +95,9 @@ export default function CourseTypesPage() { }; const handleDelete = async (id: string) => { - if (window.confirm('¿Estás seguro? Esta acción eliminará el tipo de curso.')) { + if ( + window.confirm('¿Estás seguro? Esta acción eliminará el tipo de curso.') + ) { deleteMutation.mutate(id); } }; @@ -88,9 +106,12 @@ export default function CourseTypesPage() { const payload = { name: data.name, description: data.description }; if (currentTypeId) { - updateMutation.mutate({ id: currentTypeId, data: payload }, { - onSuccess: () => setIsModalOpen(false), - }); + updateMutation.mutate( + { id: currentTypeId, data: payload }, + { + onSuccess: () => setIsModalOpen(false), + } + ); } else { createMutation.mutate(payload, { onSuccess: () => setIsModalOpen(false), @@ -98,81 +119,176 @@ export default function CourseTypesPage() { } }; - if (isLoading && courseTypes.length === 0) return

Cargando tipos de curso...

; - if (error) return

Error al cargar los datos: {error.message}

; + if (isLoading && courseTypes.length === 0) + return

Cargando tipos de curso...

; + if (error) + return ( +

+ Error al cargar los datos: {error.message} +

+ ); return ( -
-
-
-

Gestión de Tipos de Curso

-

Crea y administra las categorías de los cursos.

+
+
+
+
+

+ Gestión de Tipos de Curso +

+

+ Crea y administra las categorías de los cursos. +

+
+
- -
- - -
-
- Tipos de Curso Existentes ({totalTypes}) - Lista de todas las categorías disponibles -
-
-
- - setSearchTerm(e.target.value)} className="w-full pl-10 pr-4 py-2 text-sm border rounded-lg bg-white/80 border-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500/50" /> + + +
+
+ Tipos de Curso Existentes ({totalTypes}) + + Lista de todas las categorías disponibles +
- -
-
- - -
- {courseTypes.map((type) => ( -
-
-

{type.name}

-

{type.description}

-

{(type.courses || []).length} cursos asociados

+
+
+ + setSearchTerm(e.target.value)} + className="w-full pl-10 pr-4 py-2 text-sm border rounded-lg bg-white/80 border-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500/50" + />
-
- - + +
+
+ + +
+ {courseTypes.map((type) => ( +
+
+

+ {type.name} +

+

{type.description}

+

+ {(type.courses || []).length} cursos asociados +

+
+
+ + +
+ ))} +
+ {courseTypes.length === 0 && !isLoading && ( +

+ No se encontraron tipos de curso con los filtros aplicados. +

+ )} + + {totalPages > 1 && ( +
+ + + Página {currentPage} de {totalPages} + +
- ))} -
- {courseTypes.length === 0 && !isLoading &&

No se encontraron tipos de curso con los filtros aplicados.

} - - {totalPages > 1 && ( -
- - Página {currentPage} de {totalPages} - + )} + + + + + + + {currentTypeId ? 'Editar' : 'Crear'} Tipo de Curso + + +
+ +