diff --git a/.env.development b/.env.development new file mode 100644 index 000000000..14ea4ad49 --- /dev/null +++ b/.env.development @@ -0,0 +1 @@ +VITE_API_BASE_URL=/api diff --git a/.env.production b/.env.production new file mode 100644 index 000000000..5ac6043d1 --- /dev/null +++ b/.env.production @@ -0,0 +1 @@ +VITE_API_BASE_URL=https://dummyjson.com diff --git a/.prettierrc b/.prettierrc index d9ae6b1fb..776d639ec 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,9 +1,9 @@ { - "semi": false, - "printWidth": 120, + "semi": true, "tabWidth": 2, - "singleQuote": false, "quoteProps": "consistent", "trailingComma": "all", - "singleAttributePerLine": false -} \ No newline at end of file + "singleAttributePerLine": false, + "singleQuote": true, + +} diff --git a/convention.md b/convention.md new file mode 100644 index 000000000..8017ebb10 --- /dev/null +++ b/convention.md @@ -0,0 +1,6 @@ +### naminge 컨벤션 + +- CRUD Naming 채 + +### function 키워드 쓰기 ? 화살표 함수 쓰기? +화살표 함수 사용하기 \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js index 092408a9f..1a938657f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,14 +1,15 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' +import js from '@eslint/js'; +import fsdPlugin from 'eslint-plugin-fsd-lint'; +import reactHooks from 'eslint-plugin-react-hooks'; +import reactRefresh from 'eslint-plugin-react-refresh'; +import globals from 'globals'; +import tseslint from 'typescript-eslint'; export default tseslint.config( { ignores: ['dist'] }, { extends: [js.configs.recommended, ...tseslint.configs.recommended], - files: ['**/*.{ts,tsx}'], + files: ['**/*.{ts,tsx,css}'], languageOptions: { ecmaVersion: 2020, globals: globals.browser, @@ -16,6 +17,7 @@ export default tseslint.config( plugins: { 'react-hooks': reactHooks, 'react-refresh': reactRefresh, + 'fsd': fsdPlugin, }, rules: { ...reactHooks.configs.recommended.rules, @@ -23,6 +25,32 @@ export default tseslint.config( 'warn', { allowConstantExport: true }, ], + // Enforces FSD layer import rules (e.g., features cannot import pages) + 'fsd/forbidden-imports': 'error', + + // Disallows relative imports between slices/layers, use aliases (@) + // Allows relative imports within the same slice by default (configurable) + 'fsd/no-relative-imports': [ + 'error', + { + allowSameSlice: true, + }, + ], + + // Enforces importing only via public API (index files) + // 'fsd/no-public-api-sidestep': 'error', + + // Prevents direct imports between slices in the same layer + // 'fsd/no-cross-slice-dependency': 'error', + + // Prevents UI imports in business logic layers (e.g., entities) + // 'fsd/no-ui-in-business-logic': 'error', + + // Forbids direct import of the global store + // 'fsd/no-global-store-imports': 'error', + + // Enforces import order based on FSD layers (disabled due to prettier conflict) + // 'fsd/ordered-imports': 'warn', }, }, -) +); diff --git a/global.d.ts b/global.d.ts new file mode 100644 index 000000000..577d508da --- /dev/null +++ b/global.d.ts @@ -0,0 +1,2 @@ +declare module '*.css'; +declare module '*.module.css'; diff --git a/index_final.html b/index_final.html new file mode 100644 index 000000000..a466b11c5 --- /dev/null +++ b/index_final.html @@ -0,0 +1,15 @@ + + + + + + + + Vite + React + TS + + + +
+ + + diff --git a/package.json b/package.json index e014c5272..e7bd69de5 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,24 @@ { + "homepage": "https://yangs1s.github.io/front_6th_chapter2-3", "name": "front-end-2-3", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", - "build": "tsc -b && vite build", + "build": "tsc -b && vite build --mode production", "lint": "eslint .", "preview": "vite preview", "test": "vitest", + "deploy": "gh-pages -d dist", + "predeploy": "npm run build", "coverage": "vitest run --coverage" }, "dependencies": { + "@tanstack/react-query": "^5.84.2", "react": "^19.1.1", - "react-dom": "^19.1.1" + "react-dom": "^19.1.1", + "zustand": "^5.0.7" }, "devDependencies": { "@eslint/js": "^9.33.0", @@ -22,14 +27,17 @@ "@testing-library/jest-dom": "^6.6.4", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^14.6.1", + "@trivago/prettier-plugin-sort-imports": "^5.2.2", "@types/react": "^19.1.9", "@types/react-dom": "^19.1.7", "@vitejs/plugin-react": "^5.0.0", "axios": "^1.11.0", "class-variance-authority": "^0.7.1", "eslint": "^9.33.0", + "eslint-plugin-fsd-lint": "^1.0.9", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", + "gh-pages": "^6.3.0", "globals": "^16.3.0", "jsdom": "^26.1.0", "lucide-react": "^0.539.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b2a40d18..e1b617c26 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,18 @@ importers: .: dependencies: + '@tanstack/react-query': + specifier: ^5.84.2 + version: 5.84.2(react@19.1.1) react: specifier: ^19.1.1 version: 19.1.1 react-dom: specifier: ^19.1.1 version: 19.1.1(react@19.1.1) + zustand: + specifier: ^5.0.7 + version: 5.0.7(@types/react@19.1.9)(react@19.1.1) devDependencies: '@eslint/js': specifier: ^9.33.0 @@ -33,6 +39,9 @@ importers: '@testing-library/user-event': specifier: ^14.6.1 version: 14.6.1(@testing-library/dom@10.4.0) + '@trivago/prettier-plugin-sort-imports': + specifier: ^5.2.2 + version: 5.2.2(prettier@3.6.2) '@types/react': specifier: ^19.1.9 version: 19.1.9 @@ -51,12 +60,18 @@ importers: eslint: specifier: ^9.33.0 version: 9.33.0 + eslint-plugin-fsd-lint: + specifier: ^1.0.9 + version: 1.0.9(eslint@9.33.0) eslint-plugin-react-hooks: specifier: ^5.2.0 version: 5.2.0(eslint@9.33.0) eslint-plugin-react-refresh: specifier: ^0.4.20 version: 0.4.20(eslint@9.33.0) + gh-pages: + specifier: ^6.3.0 + version: 6.3.0 globals: specifier: ^16.3.0 version: 16.3.0 @@ -103,10 +118,6 @@ packages: '@asamuzakjp/css-color@2.8.3': resolution: {integrity: sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw==} - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} - engines: {node: '>=6.9.0'} - '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -930,6 +941,14 @@ packages: cpu: [x64] os: [win32] + '@tanstack/query-core@5.83.1': + resolution: {integrity: sha512-OG69LQgT7jSp+5pPuCfzltq/+7l2xoweggjme9vlbCPa/d7D7zaqv5vN/S82SzSYZ4EDLTxNO1PWrv49RAS64Q==} + + '@tanstack/react-query@5.84.2': + resolution: {integrity: sha512-cZadySzROlD2+o8zIfbD978p0IphuQzRWiiH3I2ugnTmz4jbjc0+TdibpwqxlzynEen8OulgAg+rzdNF37s7XQ==} + peerDependencies: + react: ^18 || ^19 + '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} @@ -959,6 +978,22 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' + '@trivago/prettier-plugin-sort-imports@5.2.2': + resolution: {integrity: sha512-fYDQA9e6yTNmA13TLVSA+WMQRc5Bn/c0EUBditUHNfMMxN7M82c38b1kEggVE3pLpZ0FwkwJkUEKMiOi52JXFA==} + engines: {node: '>18.12'} + peerDependencies: + '@vue/compiler-sfc': 3.x + prettier: 2.x - 3.x + prettier-plugin-svelte: 3.x + svelte: 4.x || 5.x + peerDependenciesMeta: + '@vue/compiler-sfc': + optional: true + prettier-plugin-svelte: + optional: true + svelte: + optional: true + '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -1179,10 +1214,17 @@ packages: aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -1260,6 +1302,13 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1331,6 +1380,10 @@ packages: detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -1344,6 +1397,9 @@ packages: electron-to-chromium@1.5.45: resolution: {integrity: sha512-vOzZS6uZwhhbkZbcRyiy99Wg+pYFV5hk+5YaECvx0+Z31NR3Tt5zS6dze2OepT6PCTzVzT0dIJItti+uAW5zmw==} + email-addresses@5.0.0: + resolution: {integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1379,10 +1435,19 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + eslint-plugin-fsd-lint@1.0.9: + resolution: {integrity: sha512-D5Rh40tX9oqD63uD4RfYK6ZfbsMOGEstTC/nbRWmE5S4AK+WB2dibISyw9LQ5BIoP77yew/SmJ7fZ1iIH5IneA==} + peerDependencies: + eslint: '>=9.0.0' + eslint-plugin-react-hooks@5.2.0: resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} engines: {node: '>=10'} @@ -1471,10 +1536,26 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + filename-reserved-regex@2.0.0: + resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} + engines: {node: '>=4'} + + filenamify@4.3.0: + resolution: {integrity: sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==} + engines: {node: '>=8'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -1499,6 +1580,10 @@ packages: resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} engines: {node: '>= 6'} + fs-extra@11.3.1: + resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==} + engines: {node: '>=14.14'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1527,6 +1612,11 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + gh-pages@6.3.0: + resolution: {integrity: sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==} + engines: {node: '>=10'} + hasBin: true + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1543,10 +1633,17 @@ packages: resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} engines: {node: '>=18'} + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -1634,6 +1731,9 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + javascript-natural-sort@0.7.1: + resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1672,6 +1772,9 @@ packages: engines: {node: '>=6'} hasBin: true + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1679,6 +1782,10 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -1713,6 +1820,10 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -1786,14 +1897,26 @@ packages: outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -1812,6 +1935,10 @@ packages: path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -1834,6 +1961,10 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -2004,6 +2135,10 @@ packages: resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} engines: {node: '>= 10'} + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2040,6 +2175,10 @@ packages: strip-literal@3.0.0: resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + strip-outer@1.0.1: + resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} + engines: {node: '>=0.10.0'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2100,6 +2239,10 @@ packages: resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} engines: {node: '>=18'} + trim-repeated@1.0.0: + resolution: {integrity: sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==} + engines: {node: '>=0.10.0'} + ts-api-utils@2.1.0: resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} @@ -2140,6 +2283,10 @@ packages: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -2345,6 +2492,24 @@ packages: resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} engines: {node: '>=18'} + zustand@5.0.7: + resolution: {integrity: sha512-Ot6uqHDW/O2VdYsKLLU8GQu8sCOM1LcoE8RwvLv9uuRT9s6SOHCKs0ZEOhxg+I1Ld+A1Q5lwx+UlKXXUoCZITg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + snapshots: '@adobe/css-tools@4.4.0': {} @@ -2362,12 +2527,6 @@ snapshots: '@csstools/css-tokenizer': 3.0.3 lru-cache: 10.4.3 - '@babel/code-frame@7.26.2': - dependencies: - '@babel/helper-validator-identifier': 7.25.9 - js-tokens: 4.0.0 - picocolors: 1.1.1 - '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.27.1 @@ -3081,9 +3240,16 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.46.2': optional: true + '@tanstack/query-core@5.83.1': {} + + '@tanstack/react-query@5.84.2(react@19.1.1)': + dependencies: + '@tanstack/query-core': 5.83.1 + react: 19.1.1 + '@testing-library/dom@10.4.0': dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.27.1 '@babel/runtime': 7.26.0 '@types/aria-query': 5.0.4 aria-query: 5.3.0 @@ -3116,6 +3282,18 @@ snapshots: dependencies: '@testing-library/dom': 10.4.0 + '@trivago/prettier-plugin-sort-imports@5.2.2(prettier@3.6.2)': + dependencies: + '@babel/generator': 7.28.0 + '@babel/parser': 7.28.0 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.2 + javascript-natural-sort: 0.7.1 + lodash: 4.17.21 + prettier: 3.6.2 + transitivePeerDependencies: + - supports-color + '@types/aria-query@5.0.4': {} '@types/babel__core@7.20.5': @@ -3347,7 +3525,7 @@ snapshots: '@vitest/utils@2.1.3': dependencies: '@vitest/pretty-format': 2.1.3 - loupe: 3.1.3 + loupe: 3.2.0 tinyrainbow: 1.2.0 '@vitest/utils@3.2.4': @@ -3393,8 +3571,12 @@ snapshots: dependencies: dequal: 2.0.3 + array-union@2.1.0: {} + assertion-error@2.0.1: {} + async@3.2.6: {} + asynckit@0.4.0: {} axios@1.11.0: @@ -3477,6 +3659,10 @@ snapshots: dependencies: delayed-stream: 1.0.0 + commander@13.1.0: {} + + commondir@1.0.1: {} + concat-map@0.0.1: {} convert-source-map@2.0.0: {} @@ -3525,6 +3711,10 @@ snapshots: detect-node-es@1.1.0: {} + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} @@ -3537,6 +3727,8 @@ snapshots: electron-to-chromium@1.5.45: {} + email-addresses@5.0.0: {} + emoji-regex@8.0.0: {} entities@4.5.0: {} @@ -3588,8 +3780,14 @@ snapshots: escalade@3.2.0: {} + escape-string-regexp@1.0.5: {} + escape-string-regexp@4.0.0: {} + eslint-plugin-fsd-lint@1.0.9(eslint@9.33.0): + dependencies: + eslint: 9.33.0 + eslint-plugin-react-hooks@5.2.0(eslint@9.33.0): dependencies: eslint: 9.33.0 @@ -3697,10 +3895,29 @@ snapshots: dependencies: flat-cache: 4.0.1 + filename-reserved-regex@2.0.0: {} + + filenamify@4.3.0: + dependencies: + filename-reserved-regex: 2.0.0 + strip-outer: 1.0.1 + trim-repeated: 1.0.0 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 + find-cache-dir@3.3.2: + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -3723,6 +3940,12 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 + fs-extra@11.3.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + fsevents@2.3.3: optional: true @@ -3752,6 +3975,16 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + gh-pages@6.3.0: + dependencies: + async: 3.2.6 + commander: 13.1.0 + email-addresses: 5.0.0 + filenamify: 4.3.0 + find-cache-dir: 3.3.2 + fs-extra: 11.3.1 + globby: 11.1.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -3764,8 +3997,19 @@ snapshots: globals@16.3.0: {} + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + gopd@1.2.0: {} + graceful-fs@4.2.11: {} + graphemer@1.4.0: {} graphql@16.9.0: {} @@ -3835,6 +4079,8 @@ snapshots: isexe@2.0.0: {} + javascript-natural-sort@0.7.1: {} + js-tokens@4.0.0: {} js-tokens@9.0.1: {} @@ -3880,6 +4126,12 @@ snapshots: json5@2.2.3: {} + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -3889,6 +4141,10 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -3917,6 +4173,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + math-intrinsics@1.1.0: {} merge2@1.4.1: {} @@ -3992,14 +4252,24 @@ snapshots: outvariant@1.4.3: {} + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 + p-try@2.2.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -4014,6 +4284,8 @@ snapshots: path-to-regexp@6.3.0: {} + path-type@4.0.0: {} + pathe@2.0.3: {} pathval@2.0.0: {} @@ -4026,6 +4298,10 @@ snapshots: picomatch@4.0.3: {} + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -4181,6 +4457,8 @@ snapshots: mrmime: 2.0.0 totalist: 3.0.1 + slash@3.0.0: {} + source-map-js@1.2.1: {} stackback@0.0.2: {} @@ -4211,6 +4489,10 @@ snapshots: dependencies: js-tokens: 9.0.1 + strip-outer@1.0.1: + dependencies: + escape-string-regexp: 1.0.5 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -4261,6 +4543,10 @@ snapshots: dependencies: punycode: 2.3.1 + trim-repeated@1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + ts-api-utils@2.1.0(typescript@5.9.2): dependencies: typescript: 5.9.2 @@ -4292,6 +4578,8 @@ snapshots: universalify@0.2.0: {} + universalify@2.0.1: {} + update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: browserslist: 4.24.2 @@ -4473,3 +4761,8 @@ snapshots: yocto-queue@0.1.0: {} yoctocolors-cjs@2.1.2: {} + + zustand@5.0.7(@types/react@19.1.9)(react@19.1.1): + optionalDependencies: + '@types/react': 19.1.9 + react: 19.1.1 diff --git a/src/App.tsx b/src/App.tsx index 0c0032aab..f446ab52d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,20 +1,26 @@ -import { BrowserRouter as Router } from "react-router-dom" -import Header from "./components/Header.tsx" -import Footer from "./components/Footer.tsx" -import PostsManagerPage from "./pages/PostsManagerPage.tsx" +import { BrowserRouter as Router } from 'react-router-dom'; + +import PostsManagerPage from '@/pages/PostsManagerPage.tsx'; +import Footer from '@/shared/ui/Footer.tsx'; +import Header from '@/shared/ui/Header.tsx'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; + +const queryClient = new QueryClient(); const App = () => { return ( - -
-
-
- -
-
-
- ) -} + + +
+
+
+ +
+
+
+
+ ); +}; -export default App +export default App; diff --git a/src/assets/react.svg b/src/app/assets/react.svg similarity index 100% rename from src/assets/react.svg rename to src/app/assets/react.svg diff --git a/src/components/index.tsx b/src/components/index.tsx deleted file mode 100644 index 8495817d3..000000000 --- a/src/components/index.tsx +++ /dev/null @@ -1,214 +0,0 @@ -import * as React from "react" -import { forwardRef } from "react" -import * as SelectPrimitive from "@radix-ui/react-select" -import * as DialogPrimitive from "@radix-ui/react-dialog" -import { Check, ChevronDown, X } from "lucide-react" -import { cva, VariantProps } from "class-variance-authority" - -const buttonVariants = cva( - "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background", - { - variants: { - variant: { - default: "bg-blue-500 text-white hover:bg-blue-600", - destructive: "bg-red-500 text-white hover:bg-red-600", - outline: "border border-gray-300 bg-transparent text-gray-700 hover:bg-gray-100", - secondary: "bg-gray-200 text-gray-800 hover:bg-gray-300", - ghost: "bg-transparent text-gray-700 hover:bg-gray-100", - link: "underline-offset-4 hover:underline text-blue-500", - }, - size: { - default: "h-10 py-2 px-4", - sm: "h-8 px-3 rounded-md text-xs", - lg: "h-11 px-8 rounded-md", - icon: "h-9 w-9", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - }, -) - -interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { - className?: string -} - -export const Button = forwardRef(({ className, variant, size, ...props }, ref) => { - return