diff --git a/.github/workflows/frontend-ci.yml b/.github/workflows/frontend-ci.yml new file mode 100644 index 0000000..0c91180 --- /dev/null +++ b/.github/workflows/frontend-ci.yml @@ -0,0 +1,38 @@ +name: Frontend CI (Vite Build) + +on: + push: + branches: [ "main" ] # 귣ġ ̸ master ʿ + pull_request: + branches: [ "main" ] + +jobs: + build-check: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x] # Vite 6.x ֽ Node (18, 20+) + + steps: + # 1. ڵ + - name: Checkout code + uses: actions/checkout@v4 + + # 2. Node.js + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + + # 3. ġ + # package-lock.json ִٸ npm ci մϴ. + # lock ٸ npm install ؼ ϼ. + - name: Install dependencies + run: npm ci + + # 4. Ȯ (ٽ ܰ) + # Vite 尡 ϸ ⼭ , PR ɴϴ. + - name: Build Project + run: npm run build \ No newline at end of file diff --git a/.screen-graph.json b/.screen-graph.json new file mode 100644 index 0000000..14f3d5c --- /dev/null +++ b/.screen-graph.json @@ -0,0 +1,1141 @@ +{ + "nodes": [ + { + "id": "src/screens/Desktop/Desktop.jsx", + "label": "Desktop", + "routes": [ + "/*", + "/desktop" + ], + "dataModelId": "45:2", + "isRoot": true + }, + { + "id": "src/screens/CommunityPage/CommunityPage.jsx", + "label": "CommunityPage", + "routes": [ + "/communitypage" + ], + "dataModelId": "1:6" + }, + { + "id": "src/screens/MyPage/MyPage.jsx", + "label": "MyPage", + "routes": [ + "/mypage" + ], + "dataModelId": "168:346" + }, + { + "id": "src/screens/RecipePage/RecipePage.jsx", + "label": "RecipePage", + "routes": [ + "/recipepage/:id" + ], + "dataModelId": "199:457" + }, + { + "id": "src/screens/CommunityContent/CommunityContent.jsx", + "label": "CommunityContent", + "routes": [ + "/communitycontentpage/:id" + ], + "dataModelId": "107:399" + }, + { + "id": "src/screens/AddIngredientPage/AddIngredientPage.jsx", + "label": "AddIngredientPage", + "routes": [ + "/addingredient" + ] + }, + { + "id": "src/screens/CreatePostPage/CreatePostPage.jsx", + "label": "CreatePostPage", + "routes": [ + "/createpost" + ] + }, + { + "id": "src/screens/MenuRecommendationPage/MenuRecommendationPage.jsx", + "label": "MenuRecommendationPage", + "routes": [ + "/menurecommendation" + ] + } + ], + "edges": [ + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:53:14-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": " setShowMenu(false)}>\n 홈\n ", + "line": 53, + "endLine": 55, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:56:14-to-src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "data": { + "viaRoute": "/menurecommendation", + "trigger": { + "element": " setShowMenu(false)}>\n 메뉴 추천\n ", + "line": 56, + "endLine": 58, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:59:14-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": " setShowMenu(false)}>\n 재료 나눔 게시판\n ", + "line": 59, + "endLine": 61, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:62:14-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": " setShowMenu(false)}>\n 마이페이지\n ", + "line": 62, + "endLine": 64, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:67:10-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n \n ", + "line": 67, + "endLine": 73, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:76:8-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n

\n 알고리즘 \n 셰프\n

\n ", + "line": 76, + "endLine": 81, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:84:10-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": "\n
마이페이지
\n ", + "line": 84, + "endLine": 86, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\screens\\Desktop\\sections\\IngredientInventory\\IngredientInventory.jsx:74:8-to-src\\screens\\AddIngredientPage\\AddIngredientPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx", + "data": { + "viaRoute": "/addingredient", + "trigger": { + "element": "\n
\n
\n
추가하기
\n
\n\n
\n \n
\n
\n ", + "line": 74, + "endLine": 88, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\screens\\Desktop\\sections\\IngredientInventory\\IngredientInventory.jsx" + } + } + }, + { + "id": "src\\screens\\Desktop\\sections\\MenuInventory\\MenuInventory.jsx:57:8-to-src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "data": { + "viaRoute": "/menurecommendation", + "trigger": { + "element": "\n \n ", + "line": 57, + "endLine": 59, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\screens\\Desktop\\sections\\MenuInventory\\MenuInventory.jsx" + } + } + }, + { + "id": "src\\screens\\Desktop\\sections\\MenuInventory\\MenuInventory.jsx:60:8-to-src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "data": { + "viaRoute": "/menurecommendation", + "trigger": { + "element": "\n 더보기 →\n ", + "line": 60, + "endLine": 62, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\screens\\Desktop\\sections\\MenuInventory\\MenuInventory.jsx" + } + } + }, + { + "id": "src\\screens\\Desktop\\sections\\Community\\Community.jsx:18:6-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": "\n
재료 나눔 게시판
\n ", + "line": 18, + "endLine": 20, + "column": 6, + "endColumn": 13, + "sourceFile": "src\\screens\\Desktop\\sections\\Community\\Community.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:53:14-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": " setShowMenu(false)}>\n 홈\n ", + "line": 53, + "endLine": 55, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:56:14-to-src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "data": { + "viaRoute": "/menurecommendation", + "trigger": { + "element": " setShowMenu(false)}>\n 메뉴 추천\n ", + "line": 56, + "endLine": 58, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:59:14-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": " setShowMenu(false)}>\n 재료 나눔 게시판\n ", + "line": 59, + "endLine": 61, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:62:14-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": " setShowMenu(false)}>\n 마이페이지\n ", + "line": 62, + "endLine": 64, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:67:10-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n \n ", + "line": 67, + "endLine": 73, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:76:8-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n

\n 알고리즘 \n 셰프\n

\n ", + "line": 76, + "endLine": 81, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:84:10-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": "\n
마이페이지
\n ", + "line": 84, + "endLine": 86, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\screens\\CommunityPage\\sections\\Communitypage\\Communitypage.jsx:54:4-to-src\\screens\\CreatePostPage\\CreatePostPage.jsx", + "source": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "target": "src\\screens\\CreatePostPage\\CreatePostPage.jsx", + "data": { + "viaRoute": "/createpost", + "trigger": { + "element": "navigate(\"/createpost\")", + "line": 54, + "endLine": 54, + "column": 4, + "endColumn": 27, + "sourceFile": "src\\screens\\CommunityPage\\sections\\Communitypage\\Communitypage.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:53:14-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": " setShowMenu(false)}>\n 홈\n ", + "line": 53, + "endLine": 55, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:56:14-to-src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "data": { + "viaRoute": "/menurecommendation", + "trigger": { + "element": " setShowMenu(false)}>\n 메뉴 추천\n ", + "line": 56, + "endLine": 58, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:59:14-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": " setShowMenu(false)}>\n 재료 나눔 게시판\n ", + "line": 59, + "endLine": 61, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:62:14-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": " setShowMenu(false)}>\n 마이페이지\n ", + "line": 62, + "endLine": 64, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:67:10-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n \n ", + "line": 67, + "endLine": 73, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:76:8-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n

\n 알고리즘 \n 셰프\n

\n ", + "line": 76, + "endLine": 81, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:84:10-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": "\n
마이페이지
\n ", + "line": 84, + "endLine": 86, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:53:14-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": " setShowMenu(false)}>\n 홈\n ", + "line": 53, + "endLine": 55, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:56:14-to-src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "data": { + "viaRoute": "/menurecommendation", + "trigger": { + "element": " setShowMenu(false)}>\n 메뉴 추천\n ", + "line": 56, + "endLine": 58, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:59:14-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": " setShowMenu(false)}>\n 재료 나눔 게시판\n ", + "line": 59, + "endLine": 61, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:62:14-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": " setShowMenu(false)}>\n 마이페이지\n ", + "line": 62, + "endLine": 64, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:67:10-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n \n ", + "line": 67, + "endLine": 73, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:76:8-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n

\n 알고리즘 \n 셰프\n

\n ", + "line": 76, + "endLine": 81, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:84:10-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": "\n
마이페이지
\n ", + "line": 84, + "endLine": 86, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:53:14-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": " setShowMenu(false)}>\n 홈\n ", + "line": 53, + "endLine": 55, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:56:14-to-src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "data": { + "viaRoute": "/menurecommendation", + "trigger": { + "element": " setShowMenu(false)}>\n 메뉴 추천\n ", + "line": 56, + "endLine": 58, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:59:14-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": " setShowMenu(false)}>\n 재료 나눔 게시판\n ", + "line": 59, + "endLine": 61, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:62:14-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": " setShowMenu(false)}>\n 마이페이지\n ", + "line": 62, + "endLine": 64, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:67:10-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n \n ", + "line": 67, + "endLine": 73, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:76:8-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n

\n 알고리즘 \n 셰프\n

\n ", + "line": 76, + "endLine": 81, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:84:10-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": "\n
마이페이지
\n ", + "line": 84, + "endLine": 86, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\screens\\CommunityContent\\sections\\Communitycontentpage\\Communitycontentpage.jsx:87:6-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\CommunityContent\\CommunityContent.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": "\n
재료 나눔 게시판
\n ", + "line": 87, + "endLine": 89, + "column": 6, + "endColumn": 13, + "sourceFile": "src\\screens\\CommunityContent\\sections\\Communitycontentpage\\Communitycontentpage.jsx" + } + } + }, + { + "id": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx:54:4-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "navigate(\"/desktop\")", + "line": 54, + "endLine": 54, + "column": 4, + "endColumn": 24, + "sourceFile": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx" + } + } + }, + { + "id": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx:118:12-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n 취소\n ", + "line": 118, + "endLine": 120, + "column": 12, + "endColumn": 19, + "sourceFile": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:53:14-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": " setShowMenu(false)}>\n 홈\n ", + "line": 53, + "endLine": 55, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:56:14-to-src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "data": { + "viaRoute": "/menurecommendation", + "trigger": { + "element": " setShowMenu(false)}>\n 메뉴 추천\n ", + "line": 56, + "endLine": 58, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:59:14-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": " setShowMenu(false)}>\n 재료 나눔 게시판\n ", + "line": 59, + "endLine": 61, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:62:14-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": " setShowMenu(false)}>\n 마이페이지\n ", + "line": 62, + "endLine": 64, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:67:10-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n \n ", + "line": 67, + "endLine": 73, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:76:8-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n

\n 알고리즘 \n 셰프\n

\n ", + "line": 76, + "endLine": 81, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:84:10-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": "\n
마이페이지
\n ", + "line": 84, + "endLine": 86, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\screens\\CreatePostPage\\CreatePostPage.jsx:16:6-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\CreatePostPage\\CreatePostPage.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": "navigate(\"/communitypage\")", + "line": 16, + "endLine": 16, + "column": 6, + "endColumn": 32, + "sourceFile": "src\\screens\\CreatePostPage\\CreatePostPage.jsx" + } + } + }, + { + "id": "src\\screens\\CreatePostPage\\CreatePostPage.jsx:49:4-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\CreatePostPage\\CreatePostPage.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": "navigate(\"/communitypage\")", + "line": 49, + "endLine": 49, + "column": 4, + "endColumn": 30, + "sourceFile": "src\\screens\\CreatePostPage\\CreatePostPage.jsx" + } + } + }, + { + "id": "src\\screens\\CreatePostPage\\CreatePostPage.jsx:88:12-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\CreatePostPage\\CreatePostPage.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": "\n 취소\n ", + "line": 88, + "endLine": 90, + "column": 12, + "endColumn": 19, + "sourceFile": "src\\screens\\CreatePostPage\\CreatePostPage.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:53:14-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": " setShowMenu(false)}>\n 홈\n ", + "line": 53, + "endLine": 55, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:56:14-to-src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "data": { + "viaRoute": "/menurecommendation", + "trigger": { + "element": " setShowMenu(false)}>\n 메뉴 추천\n ", + "line": 56, + "endLine": 58, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:59:14-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": " setShowMenu(false)}>\n 재료 나눔 게시판\n ", + "line": 59, + "endLine": 61, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:62:14-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": " setShowMenu(false)}>\n 마이페이지\n ", + "line": 62, + "endLine": 64, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:67:10-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n \n ", + "line": 67, + "endLine": 73, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:76:8-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n

\n 알고리즘 \n 셰프\n

\n ", + "line": 76, + "endLine": 81, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:84:10-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": "\n
마이페이지
\n ", + "line": 84, + "endLine": 86, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:53:14-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": " setShowMenu(false)}>\n 홈\n ", + "line": 53, + "endLine": 55, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:56:14-to-src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MenuRecommendationPage\\MenuRecommendationPage.jsx", + "data": { + "viaRoute": "/menurecommendation", + "trigger": { + "element": " setShowMenu(false)}>\n 메뉴 추천\n ", + "line": 56, + "endLine": 58, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:59:14-to-src\\screens\\CommunityPage\\CommunityPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\CommunityPage\\CommunityPage.jsx", + "data": { + "viaRoute": "/communitypage", + "trigger": { + "element": " setShowMenu(false)}>\n 재료 나눔 게시판\n ", + "line": 59, + "endLine": 61, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:62:14-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": " setShowMenu(false)}>\n 마이페이지\n ", + "line": 62, + "endLine": 64, + "column": 14, + "endColumn": 21, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:67:10-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n \n ", + "line": 67, + "endLine": 73, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:76:8-to-src\\screens\\Desktop\\Desktop.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\Desktop\\Desktop.jsx", + "data": { + "viaRoute": "/desktop", + "trigger": { + "element": "\n

\n 알고리즘 \n 셰프\n

\n ", + "line": 76, + "endLine": 81, + "column": 8, + "endColumn": 15, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + }, + { + "id": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx:84:10-to-src\\screens\\MyPage\\MyPage.jsx", + "source": "src\\screens\\Desktop\\Desktop.jsx", + "target": "src\\screens\\MyPage\\MyPage.jsx", + "data": { + "viaRoute": "/mypage", + "trigger": { + "element": "\n
마이페이지
\n ", + "line": 84, + "endLine": 86, + "column": 10, + "endColumn": 17, + "sourceFile": "src\\components\\UnifiedHeader\\UnifiedHeader.jsx" + } + } + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index f665eb6..6486779 100644 --- a/README.md +++ b/README.md @@ -1 +1,124 @@ -AlgorithmChef_Frontend +# 알고리즘 셰프 - Algorithm Chef + +환영합니다! 이 프로젝트는 Anima에 의해 자동으로 생성된 React 애플리케이션입니다. +"알고리즘 셰프"는 사용자의 냉장고 속 식재료와 개인 성향을 기반으로 맞춤형 레시피를 추천하고, 식재료 나눔 커뮤니티를 제공하는 서비스입니다. + +## 시작하기 + +> **전제 조건:** +> 다음 단계를 수행하려면 시스템에 [NodeJS](https://nodejs.org/en/)가 설치되어 있어야 합니다. + +프로젝트를 시작하려면 먼저 다음 명령어로 의존성을 설치해야 합니다: + +```bash +npm install +``` + +그 다음, 다음 명령어로 개발 버전을 실행할 수 있습니다: + +```bash +npm run dev +``` + +몇 초 후, 프로젝트는 [http://localhost:5173/](http://localhost:5173/) 주소에서 접근할 수 있습니다. + +결과에 만족하면, 다음 명령어로 릴리스용 프로젝트를 빌드할 수 있습니다: + +```bash +npm run build +``` + +## 주요 기능 + +* **반응형 디자인**: 모든 페이지는 다양한 화면 크기(데스크톱, 태블릿, 모바일)에 최적화되어 있습니다. +* **통합 헤더**: 모든 페이지에 일관된 탐색 및 인증 기능을 제공하는 단일 헤더 컴포넌트가 적용되었습니다. +* **메뉴 내비게이션**: 헤더 좌측의 햄버거 메뉴를 통해 주요 페이지(홈, 메뉴 추천, 재료 나눔 게시판, 마이페이지)로 쉽게 이동할 수 있습니다. +* **사용자 인증**: + * 로그인 및 회원가입 팝업 시스템. + * 성별, 생년월일 입력 및 성향(건강 목표, 알레르기, 선호/비선호 재료, 선호 요리, 매운맛 선호도, 알림 설정) 선택 기능. + * 로그인 시 사용자 이름 표시 및 로그아웃 버튼으로 전환. + * 아이디/비밀번호 유효성 검사 및 중복 아이디 확인 (현재 `localStorage` 기반 목업). +* **나의 냉장고**: + * 식재료 목록을 카테고리별로 필터링하고 검색할 수 있습니다. + * 새로운 식재료를 추가하거나 영수증을 등록할 수 있는 기능 (팝업 및 전용 페이지). +* **메뉴 추천**: + * Gemini API와 연동될 검색창 (현재 목업). + * 식재료 기반 및 성향 기반 자동 메뉴 추천 기능. + * 레시피 카드를 최대 12개까지 표시하며, 좌우 스크롤 버튼으로 페이지 이동 가능. + * 각 레시피 카드를 클릭하면 상세 레시피 페이지로 이동합니다. +* **재료 나눔 게시판**: + * 게시글 목록을 페이지네이션(최대 5페이지)으로 탐색할 수 있습니다. + * 로그인한 사용자만 새 글을 작성할 수 있습니다. + * 각 게시글은 고유한 댓글 기능을 가지며, 댓글은 `localStorage`에 저장됩니다. + * 게시글 상세 페이지에서 현재 게시글의 앞뒤 2개씩, 총 4개의 관련 게시글을 표시합니다. +* **마이페이지**: + * 로그인 상태에 따라 사용자 성향 정보를 표시하거나 로그인 요청 메시지를 출력합니다. + * 사용자의 건강 목표, 알레르기, 선호/비선호 재료, 선호 요리, 매운맛 선호도, 알림 설정을 확인할 수 있습니다. + +## 백엔드 연동 가이드 + +이 프로젝트는 프론트엔드 기능 구현에 중점을 두었으며, 모든 데이터는 현재 `localStorage`를 사용하여 목업(mockup)으로 처리됩니다. 실제 백엔드와 연동하려면 다음 지침을 따르세요: + +1. **API 클라이언트 설치**: `axios`와 같은 HTTP 클라이언트 라이브러리를 설치합니다. + ```bash + npm install axios + ``` + +2. **API 엔드포인트 정의**: 백엔드에서 제공하는 API 엔드포인트를 정의합니다. 예: + * `GET /api/users/{username}/ingredients` (사용자 냉장고 재료) + * `GET /api/ingredients/all` (모든 식재료 DB) + * `POST /api/ingredients` (식재료 추가) + * `POST /api/login` (로그인) + * `POST /api/signup` (회원가입) + * `POST /api/users/{username}/preferences` (사용자 성향 저장) + * `GET /api/users/{username}/preferences` (사용자 성향 조회) + * `GET /api/posts` (모든 게시글) + * `POST /api/posts` (새 게시글 작성) + * `GET /api/posts/{id}/comments` (게시글 댓글 조회) + * `POST /api/posts/{id}/comments` (댓글 작성) + * `GET /api/recommend/ingredients` (식재료 기반 레시피 추천) + * `GET /api/recommend/tendencies` (성향 기반 레시피 추천) + * `POST /api/gemini-search` (Gemini API 검색) + +3. **목업 데이터 교체**: 프로젝트 코드 내의 `// TODO: Backend Integration: Replace with API call` 주석을 찾아 `localStorage`를 사용하는 목업 로직을 실제 `axios` 호출로 교체합니다. + + **예시 (로그인):** + ```javascript + // src/components/LoginPopup/LoginPopup.jsx + const handleLogin = async (e) => { + e.preventDefault(); + try { + const response = await axios.post('/api/login', { username, password }); + login(response.data.user); // Assuming backend returns user data + onClose(); + } catch (error) { + alert("아이디 또는 비밀번호가 일치하지 않습니다."); + console.error("Login error:", error); + } + }; + ``` + + **예시 (게시글 목록):** + ```javascript + // src/screens/CommunityPage/sections/Communitypage/Communitypage.jsx + useEffect(() => { + const fetchPosts = async () => { + try { + const response = await axios.get('/api/posts'); + setAllPosts(response.data); + } catch (error) { + console.error("Failed to fetch posts:", error); + setAllPosts(DEFAULT_POSTS); // Fallback to default posts + } + }; + fetchPosts(); + }, []); + ``` + +4. **환경 변수 설정**: API의 기본 URL 등은 `.env` 파일을 사용하여 관리하는 것이 좋습니다. + ``` + VITE_API_BASE_URL=http://localhost:8080/api + ``` + 그리고 코드에서는 `import.meta.env.VITE_API_BASE_URL`과 같이 접근합니다. + +이 가이드를 통해 "알고리즘 셰프" 프론트엔드를 실제 백엔드 서비스와 성공적으로 연동할 수 있을 것입니다. diff --git a/eslint.config.js b/eslint.config.js deleted file mode 100644 index cee1e2c..0000000 --- a/eslint.config.js +++ /dev/null @@ -1,29 +0,0 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import { defineConfig, globalIgnores } from 'eslint/config' - -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{js,jsx}'], - extends: [ - js.configs.recommended, - reactHooks.configs['recommended-latest'], - reactRefresh.configs.vite, - ], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - parserOptions: { - ecmaVersion: 'latest', - ecmaFeatures: { jsx: true }, - sourceType: 'module', - }, - }, - rules: { - 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], - }, - }, -]) diff --git a/index.html b/index.html index d7c6abc..6ba856d 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,35 @@ - + - - - - algorithmcheffront + + 알고리즘 셰프 - Algorithm Chef + + + -
- +
+ diff --git a/package-lock.json b/package-lock.json index 8a0e906..10817b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,27 +1,528 @@ { - "name": "algorithmcheffront", - "version": "0.0.0", + "name": "anima-project", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "algorithmcheffront", - "version": "0.0.0", + "name": "anima-project", + "version": "1.0.0", "dependencies": { - "react": "^19.1.1", - "react-dom": "^19.1.1" + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.8.1" }, "devDependencies": { - "@eslint/js": "^9.36.0", - "@types/react": "^19.1.16", - "@types/react-dom": "^19.1.9", - "@vitejs/plugin-react": "^5.0.4", - "babel-plugin-react-compiler": "^19.1.0-rc.3", - "eslint": "^9.36.0", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.22", - "globals": "^16.4.0", - "vite": "^7.1.7" + "@animaapp/vite-plugin-screen-graph": "^0.1.5", + "@vitejs/plugin-react": "4.3.4", + "esbuild": "0.24.0", + "globals": "15.12.0", + "vite": "6.0.4" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@animaapp/vite-plugin-screen-graph/-/vite-plugin-screen-graph-0.1.11.tgz", + "integrity": "sha512-fTq3NEQaJMqVxY87iSbB18FDmotkXmfP+80Ch9v8MuwI4SB58KvGqrpLt1TuyM3kTLpTvZWSkkDMTOved8m0cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.24.1", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.27.0", + "estree-walker": "^3.0.3", + "fast-glob": "^3.2.12", + "vite": "^5.0.0" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/@animaapp/vite-plugin-screen-graph/node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } } }, "node_modules/@babel/code-frame": { @@ -308,9 +809,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", "cpu": [ "ppc64" ], @@ -325,9 +826,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", "cpu": [ "arm" ], @@ -342,9 +843,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", "cpu": [ "arm64" ], @@ -359,9 +860,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", "cpu": [ "x64" ], @@ -376,9 +877,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", "cpu": [ "arm64" ], @@ -393,9 +894,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", "cpu": [ "x64" ], @@ -410,9 +911,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", "cpu": [ "arm64" ], @@ -427,9 +928,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", "cpu": [ "x64" ], @@ -444,9 +945,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", "cpu": [ "arm" ], @@ -461,9 +962,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", "cpu": [ "arm64" ], @@ -478,9 +979,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", "cpu": [ "ia32" ], @@ -495,9 +996,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", "cpu": [ "loong64" ], @@ -512,9 +1013,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", "cpu": [ "mips64el" ], @@ -529,9 +1030,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", "cpu": [ "ppc64" ], @@ -546,9 +1047,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", "cpu": [ "riscv64" ], @@ -563,9 +1064,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", "cpu": [ "s390x" ], @@ -580,9 +1081,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", "cpu": [ "x64" ], @@ -596,27 +1097,10 @@ "node": ">=18" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", "cpu": [ "x64" ], @@ -631,9 +1115,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", "cpu": [ "arm64" ], @@ -648,9 +1132,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", "cpu": [ "x64" ], @@ -664,27 +1148,10 @@ "node": ">=18" } }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", "cpu": [ "x64" ], @@ -699,9 +1166,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", "cpu": [ "arm64" ], @@ -716,9 +1183,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", "cpu": [ "ia32" ], @@ -733,9 +1200,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", "cpu": [ "x64" ], @@ -749,215 +1216,6 @@ "node": ">=18" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/js": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -1008,17 +1266,57 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.43", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.43.tgz", - "integrity": "sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==", - "dev": true, - "license": "MIT" + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@remix-run/router": { + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.1.tgz", + "integrity": "sha512-vDbaOzF7yT2Qs4vO6XV1MHcJv+3dgR1sT+l3B8xxOVhUC336prMvqrvsLL/9Dnw2xr6Qhz4J0dmS0llNAbnUmQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.1.tgz", - "integrity": "sha512-bxZtughE4VNVJlL1RdoSE545kc4JxL7op57KKoi59/gwuU5rV6jLWFXXc8jwgFoT6vtj+ZjO+Z2C5nrY0Cl6wA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", + "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", "cpu": [ "arm" ], @@ -1030,9 +1328,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.1.tgz", - "integrity": "sha512-44a1hreb02cAAfAKmZfXVercPFaDjqXCK+iKeVOlJ9ltvnO6QqsBHgKVPTu+MJHSLLeMEUbeG2qiDYgbFPU48g==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", + "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", "cpu": [ "arm64" ], @@ -1044,9 +1342,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.1.tgz", - "integrity": "sha512-usmzIgD0rf1syoOZ2WZvy8YpXK5G1V3btm3QZddoGSa6mOgfXWkkv+642bfUUldomgrbiLQGrPryb7DXLovPWQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", + "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", "cpu": [ "arm64" ], @@ -1058,9 +1356,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.1.tgz", - "integrity": "sha512-is3r/k4vig2Gt8mKtTlzzyaSQ+hd87kDxiN3uDSDwggJLUV56Umli6OoL+/YZa/KvtdrdyNfMKHzL/P4siOOmg==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", + "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", "cpu": [ "x64" ], @@ -1072,9 +1370,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.1.tgz", - "integrity": "sha512-QJ1ksgp/bDJkZB4daldVmHaEQkG4r8PUXitCOC2WRmRaSaHx5RwPoI3DHVfXKwDkB+Sk6auFI/+JHacTekPRSw==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", + "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", "cpu": [ "arm64" ], @@ -1086,9 +1384,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.1.tgz", - "integrity": "sha512-J6ma5xgAzvqsnU6a0+jgGX/gvoGokqpkx6zY4cWizRrm0ffhHDpJKQgC8dtDb3+MqfZDIqs64REbfHDMzxLMqQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", + "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", "cpu": [ "x64" ], @@ -1100,9 +1398,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.1.tgz", - "integrity": "sha512-JzWRR41o2U3/KMNKRuZNsDUAcAVUYhsPuMlx5RUldw0E4lvSIXFUwejtYz1HJXohUmqs/M6BBJAUBzKXZVddbg==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", + "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", "cpu": [ "arm" ], @@ -1114,9 +1412,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.1.tgz", - "integrity": "sha512-L8kRIrnfMrEoHLHtHn+4uYA52fiLDEDyezgxZtGUTiII/yb04Krq+vk3P2Try+Vya9LeCE9ZHU8CXD6J9EhzHQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", + "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", "cpu": [ "arm" ], @@ -1128,9 +1426,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.1.tgz", - "integrity": "sha512-ysAc0MFRV+WtQ8li8hi3EoFi7us6d1UzaS/+Dp7FYZfg3NdDljGMoVyiIp6Ucz7uhlYDBZ/zt6XI0YEZbUO11Q==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", + "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", "cpu": [ "arm64" ], @@ -1142,9 +1440,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.1.tgz", - "integrity": "sha512-UV6l9MJpDbDZZ/fJvqNcvO1PcivGEf1AvKuTcHoLjVZVFeAMygnamCTDikCVMRnA+qJe+B3pSbgX2+lBMqgBhA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", + "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", "cpu": [ "arm64" ], @@ -1156,9 +1454,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.1.tgz", - "integrity": "sha512-UDUtelEprkA85g95Q+nj3Xf0M4hHa4DiJ+3P3h4BuGliY4NReYYqwlc0Y8ICLjN4+uIgCEvaygYlpf0hUj90Yg==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", + "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", "cpu": [ "loong64" ], @@ -1170,9 +1468,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.1.tgz", - "integrity": "sha512-vrRn+BYhEtNOte/zbc2wAUQReJXxEx2URfTol6OEfY2zFEUK92pkFBSXRylDM7aHi+YqEPJt9/ABYzmcrS4SgQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", + "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", "cpu": [ "ppc64" ], @@ -1184,9 +1482,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.1.tgz", - "integrity": "sha512-gto/1CxHyi4A7YqZZNznQYrVlPSaodOBPKM+6xcDSCMVZN/Fzb4K+AIkNz/1yAYz9h3Ng+e2fY9H6bgawVq17w==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", + "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", "cpu": [ "riscv64" ], @@ -1198,9 +1496,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.1.tgz", - "integrity": "sha512-KZ6Vx7jAw3aLNjFR8eYVcQVdFa/cvBzDNRFM3z7XhNNunWjA03eUrEwJYPk0G8V7Gs08IThFKcAPS4WY/ybIrQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", + "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", "cpu": [ "riscv64" ], @@ -1212,9 +1510,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.1.tgz", - "integrity": "sha512-HvEixy2s/rWNgpwyKpXJcHmE7om1M89hxBTBi9Fs6zVuLU4gOrEMQNbNsN/tBVIMbLyysz/iwNiGtMOpLAOlvA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", + "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", "cpu": [ "s390x" ], @@ -1226,9 +1524,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.1.tgz", - "integrity": "sha512-E/n8x2MSjAQgjj9IixO4UeEUeqXLtiA7pyoXCFYLuXpBA/t2hnbIdxHfA7kK9BFsYAoNU4st1rHYdldl8dTqGA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", + "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", "cpu": [ "x64" ], @@ -1240,9 +1538,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.1.tgz", - "integrity": "sha512-IhJ087PbLOQXCN6Ui/3FUkI9pWNZe/Z7rEIVOzMsOs1/HSAECCvSZ7PkIbkNqL/AZn6WbZvnoVZw/qwqYMo4/w==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", + "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", "cpu": [ "x64" ], @@ -1254,9 +1552,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.1.tgz", - "integrity": "sha512-0++oPNgLJHBblreu0SFM7b3mAsBJBTY0Ksrmu9N6ZVrPiTkRgda52mWR7TKhHAsUb9noCjFvAw9l6ZO1yzaVbA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", + "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", "cpu": [ "arm64" ], @@ -1268,9 +1566,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.1.tgz", - "integrity": "sha512-VJXivz61c5uVdbmitLkDlbcTk9Or43YC2QVLRkqp86QoeFSqI81bNgjhttqhKNMKnQMWnecOCm7lZz4s+WLGpQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", + "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", "cpu": [ "arm64" ], @@ -1282,9 +1580,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.1.tgz", - "integrity": "sha512-NmZPVTUOitCXUH6erJDzTQ/jotYw4CnkMDjCYRxNHVD9bNyfrGoIse684F9okwzKCV4AIHRbUkeTBc9F2OOH5Q==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", + "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", "cpu": [ "ia32" ], @@ -1296,9 +1594,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.1.tgz", - "integrity": "sha512-2SNj7COIdAf6yliSpLdLG8BEsp5lgzRehgfkP0Av8zKfQFKku6JcvbobvHASPJu4f3BFxej5g+HuQPvqPhHvpQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", "cpu": [ "x64" ], @@ -1310,9 +1608,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.1.tgz", - "integrity": "sha512-rLarc1Ofcs3DHtgSzFO31pZsCh8g05R2azN1q3fF+H423Co87My0R+tazOEvYVKXSLh8C4LerMK41/K7wlklcg==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", "cpu": [ "x64" ], @@ -1375,161 +1673,53 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "19.2.2", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", - "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.2", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", - "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, "node_modules/@vitejs/plugin-react": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.0.tgz", - "integrity": "sha512-4LuWrg7EKWgQaMJfnN+wcmbAW+VSsCmqGohftWjuct47bv8uE4n/nPpq4XjJPsxgq00GGG5J8dvBczp8uxScew==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", + "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.28.4", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.43", + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", - "react-refresh": "^0.18.0" + "react-refresh": "^0.14.2" }, "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" + "node": "^14.18.0 || >=16.0.0" }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/babel-plugin-react-compiler": { - "version": "19.1.0-rc.3", - "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-19.1.0-rc.3.tgz", - "integrity": "sha512-mjRn69WuTz4adL0bXGx8Rsyk1086zFJeKmes6aK0xPuK3aaXmDJdLHqwKKMrpm6KAI1MCoUK72d2VeqQbu8YIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.26.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, "node_modules/baseline-browser-mapping": { - "version": "2.8.25", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz", - "integrity": "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==", + "version": "2.8.30", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.30.tgz", + "integrity": "sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA==", "dev": true, "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" } }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.27.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", - "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", + "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", "dev": true, "funding": [ { @@ -1548,10 +1738,10 @@ "license": "MIT", "peer": true, "dependencies": { - "baseline-browser-mapping": "^2.8.19", - "caniuse-lite": "^1.0.30001751", - "electron-to-chromium": "^1.5.238", - "node-releases": "^2.0.26", + "baseline-browser-mapping": "^2.8.25", + "caniuse-lite": "^1.0.30001754", + "electron-to-chromium": "^1.5.249", + "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": { @@ -1561,20 +1751,10 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/caniuse-lite": { - "version": "1.0.30001754", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", - "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", + "version": "1.0.30001756", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001756.tgz", + "integrity": "sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A==", "dev": true, "funding": [ { @@ -1592,50 +1772,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -1643,28 +1779,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true, - "license": "MIT" - }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -1683,24 +1797,17 @@ } } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, "node_modules/electron-to-chromium": { - "version": "1.5.249", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz", - "integrity": "sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg==", + "version": "1.5.259", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.259.tgz", + "integrity": "sha512-I+oLXgpEJzD6Cwuwt1gYjxsDmu/S/Kd41mmLA3O+/uH2pFRO/DvOjUyGozL8j3KeLV6WyZ7ssPwELMsXCcsJAQ==", "dev": true, "license": "ISC" }, "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1711,32 +1818,30 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" } }, "node_modules/escalade": { @@ -1749,287 +1854,56 @@ "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", - "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.1", - "@eslint/plugin-kit": "^0.4.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", - "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.24.tgz", - "integrity": "sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==", + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", - "peerDependencies": { - "eslint": ">=8.40" - } - }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "@types/estree": "^1.0.0" } }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^4.0.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" }, "engines": { - "node": ">=16.0.0" + "node": ">=8.6.0" } }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "reusify": "^1.0.4" } }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=16" + "node": ">=8" } }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2047,85 +1921,38 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", - "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", "engines": { - "node": ">= 4" + "node": ">=6.9.0" } }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 6" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/globals": { + "version": "15.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.12.0.tgz", + "integrity": "sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.8.19" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-extglob": { @@ -2151,33 +1978,22 @@ "node": ">=0.10.0" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -2191,27 +2007,6 @@ "node": ">=6" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -2225,53 +2020,18 @@ "node": ">=6" } }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "license": "MIT", "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" + "js-tokens": "^3.0.0 || ^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "loose-envify": "cli.js" } }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2282,17 +2042,28 @@ "yallist": "^3.0.2" } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "ISC", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { - "node": "*" + "node": ">=8.6" } }, "node_modules/ms": { @@ -2321,13 +2092,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, "node_modules/node-releases": { "version": "2.0.27", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", @@ -2335,89 +2099,6 @@ "dev": true, "license": "MIT" }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -2426,14 +2107,13 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">=12" + "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -2468,72 +2148,111 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, "node_modules/react": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", - "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", - "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", + "peer": true, "dependencies": { - "scheduler": "^0.27.0" + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^19.2.0" + "react": "^18.3.1" } }, "node_modules/react-refresh": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", - "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "node_modules/react-router": { + "version": "6.30.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.2.tgz", + "integrity": "sha512-H2Bm38Zu1bm8KUE5NVWRMzuIyAV8p/JrOaBJAwVmp37AXG72+CZJlEBw6pdn9i5TBgLMhNDgijS4ZlblpHyWTA==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.2.tgz", + "integrity": "sha512-l2OwHn3UUnEVUqc6/1VMmR1cvZryZ3j3NzapC2eUXO1dB0sYp5mvwdjiXhpUbRb21eFow3qSxpP8Yv6oAU824Q==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.1", + "react-router": "6.30.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, "node_modules/rollup": { - "version": "4.53.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.1.tgz", - "integrity": "sha512-n2I0V0lN3E9cxxMqBCT3opWOiQBzRN7UG60z/WDKqdX2zHUS/39lezBcsckZFsV6fUTSnfqI7kHf60jDAPGKug==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", + "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", "dev": true, "license": "MIT", "dependencies": { @@ -2547,36 +2266,63 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.53.1", - "@rollup/rollup-android-arm64": "4.53.1", - "@rollup/rollup-darwin-arm64": "4.53.1", - "@rollup/rollup-darwin-x64": "4.53.1", - "@rollup/rollup-freebsd-arm64": "4.53.1", - "@rollup/rollup-freebsd-x64": "4.53.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.53.1", - "@rollup/rollup-linux-arm-musleabihf": "4.53.1", - "@rollup/rollup-linux-arm64-gnu": "4.53.1", - "@rollup/rollup-linux-arm64-musl": "4.53.1", - "@rollup/rollup-linux-loong64-gnu": "4.53.1", - "@rollup/rollup-linux-ppc64-gnu": "4.53.1", - "@rollup/rollup-linux-riscv64-gnu": "4.53.1", - "@rollup/rollup-linux-riscv64-musl": "4.53.1", - "@rollup/rollup-linux-s390x-gnu": "4.53.1", - "@rollup/rollup-linux-x64-gnu": "4.53.1", - "@rollup/rollup-linux-x64-musl": "4.53.1", - "@rollup/rollup-openharmony-arm64": "4.53.1", - "@rollup/rollup-win32-arm64-msvc": "4.53.1", - "@rollup/rollup-win32-ia32-msvc": "4.53.1", - "@rollup/rollup-win32-x64-gnu": "4.53.1", - "@rollup/rollup-win32-x64-msvc": "4.53.1", + "@rollup/rollup-android-arm-eabi": "4.53.3", + "@rollup/rollup-android-arm64": "4.53.3", + "@rollup/rollup-darwin-arm64": "4.53.3", + "@rollup/rollup-darwin-x64": "4.53.3", + "@rollup/rollup-freebsd-arm64": "4.53.3", + "@rollup/rollup-freebsd-x64": "4.53.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", + "@rollup/rollup-linux-arm-musleabihf": "4.53.3", + "@rollup/rollup-linux-arm64-gnu": "4.53.3", + "@rollup/rollup-linux-arm64-musl": "4.53.3", + "@rollup/rollup-linux-loong64-gnu": "4.53.3", + "@rollup/rollup-linux-ppc64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-musl": "4.53.3", + "@rollup/rollup-linux-s390x-gnu": "4.53.3", + "@rollup/rollup-linux-x64-gnu": "4.53.3", + "@rollup/rollup-linux-x64-musl": "4.53.3", + "@rollup/rollup-openharmony-arm64": "4.53.3", + "@rollup/rollup-win32-arm64-msvc": "4.53.3", + "@rollup/rollup-win32-ia32-msvc": "4.53.3", + "@rollup/rollup-win32-x64-gnu": "4.53.3", + "@rollup/rollup-win32-x64-msvc": "4.53.3", "fsevents": "~2.3.2" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "license": "MIT" + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } }, "node_modules/semver": { "version": "6.3.1", @@ -2588,29 +2334,6 @@ "semver": "bin/semver.js" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -2621,60 +2344,17 @@ "node": ">=0.10.0" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1" + "is-number": "^7.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8.0" } }, "node_modules/update-browserslist-db": { @@ -2708,36 +2388,23 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/vite": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz", - "integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.4.tgz", + "integrity": "sha512-zwlH6ar+6o6b4Wp+ydhtIKLrGM/LoqZzcdVmkGAFun0KHTzIzjh+h0kungEx7KJg/PYnC80I4TII9WkjciSR6Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" + "esbuild": "^0.24.0", + "postcss": "^8.4.49", + "rollup": "^4.23.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -2746,14 +2413,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", - "less": "^4.0.0", + "less": "*", "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" @@ -2794,51 +2461,12 @@ } } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } } } } diff --git a/package.json b/package.json index 8c3bc9d..eb97940 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,23 @@ { - "name": "algorithmcheffront", - "private": true, - "version": "0.0.0", + "name": "anima-project", + "version": "1.0.0", + "description": "A React project automatically generated by Anima, the design-to-code platform", + "source": "./index.html", "type": "module", "scripts": { "dev": "vite", - "build": "vite build", - "lint": "eslint .", - "preview": "vite preview" + "build": "vite build" }, "dependencies": { - "react": "^19.1.1", - "react-dom": "^19.1.1" + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.8.1" }, "devDependencies": { - "@eslint/js": "^9.36.0", - "@types/react": "^19.1.16", - "@types/react-dom": "^19.1.9", - "@vitejs/plugin-react": "^5.0.4", - "babel-plugin-react-compiler": "^19.1.0-rc.3", - "eslint": "^9.36.0", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.22", - "globals": "^16.4.0", - "vite": "^7.1.7" + "@animaapp/vite-plugin-screen-graph": "^0.1.5", + "@vitejs/plugin-react": "4.3.4", + "esbuild": "0.24.0", + "globals": "15.12.0", + "vite": "6.0.4" } } diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/App.css b/src/App.css deleted file mode 100644 index b9d355d..0000000 --- a/src/App.css +++ /dev/null @@ -1,42 +0,0 @@ -#root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} diff --git a/src/App.jsx b/src/App.jsx index f67355a..5c31980 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,35 +1,58 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from '/vite.svg' -import './App.css' +import React from "react"; +import { RouterProvider, createBrowserRouter } from "react-router-dom"; +import { AuthProvider } from "./contexts/AuthContext"; +import { CommunityContent } from "./screens/CommunityContent"; +import { CommunityPage } from "./screens/CommunityPage"; +import { Desktop } from "./screens/Desktop"; +import { MyPage } from "./screens/MyPage"; +import { RecipePage } from "./screens/RecipePage"; +import { AddIngredientPage } from "./screens/AddIngredientPage"; +import { CreatePostPage } from "./screens/CreatePostPage"; +import { MenuRecommendationPage } from "./screens/MenuRecommendationPage"; -function App() { - const [count, setCount] = useState(0) +const router = createBrowserRouter([ + { + path: "/*", + element: , + }, + { + path: "/desktop", + element: , + }, + { + path: "/communitypage", + element: , + }, + { + path: "/mypage", + element: , + }, + { + path: "/recipepage/:id", + element: , + }, + { + path: "/communitycontentpage/:id", + element: , + }, + { + path: "/addingredient", + element: , + }, + { + path: "/createpost", + element: , + }, + { + path: "/menurecommendation", + element: , + }, +]); +export const App = () => { return ( - <> - -

Vite + React

-
- -

- Edit src/App.jsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

- - ) -} - -export default App + + + + ); +}; diff --git a/src/assets/react.svg b/src/assets/react.svg deleted file mode 100644 index 6c87de9..0000000 --- a/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/components/AddIngredientPopup/AddIngredientPopup.jsx b/src/components/AddIngredientPopup/AddIngredientPopup.jsx new file mode 100644 index 0000000..63381f8 --- /dev/null +++ b/src/components/AddIngredientPopup/AddIngredientPopup.jsx @@ -0,0 +1,89 @@ +import React, { useState } from "react"; +import "./style.css"; + +const CATEGORIES = ["육류", "채소류", "가공류", "유제품", "기타"]; + +export const AddIngredientPopup = ({ onClose, onAdd }) => { + const [name, setName] = useState(""); + const [category, setCategory] = useState("채소류"); + const [expiryDays, setExpiryDays] = useState(""); + + const handleSubmit = (e) => { + e.preventDefault(); + + if (!name || !expiryDays) { + alert("모든 필드를 입력해주세요."); + return; + } + + const newIngredient = { + id: Date.now(), + name, + category, + expiryDays: parseInt(expiryDays), + image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" + }; + + // TODO: Send to backend + console.log("Adding ingredient via receipt:", newIngredient); + onAdd(newIngredient); + onClose(); + }; + + return ( +
+
e.stopPropagation()}> + + +
+

식재료 추가

+
+ +
+
+ + setName(e.target.value)} + placeholder="예: 양파" + required + /> +
+ +
+ + +
+ +
+ + setExpiryDays(e.target.value)} + placeholder="예: 7" + min="1" + required + /> +
+ + +
+
+
+ ); +}; diff --git a/src/components/AddIngredientPopup/index.js b/src/components/AddIngredientPopup/index.js new file mode 100644 index 0000000..f656586 --- /dev/null +++ b/src/components/AddIngredientPopup/index.js @@ -0,0 +1 @@ +export { AddIngredientPopup } from "./AddIngredientPopup"; diff --git a/src/components/AddIngredientPopup/style.css b/src/components/AddIngredientPopup/style.css new file mode 100644 index 0000000..4463c52 --- /dev/null +++ b/src/components/AddIngredientPopup/style.css @@ -0,0 +1,136 @@ +.add-ingredient-popup-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + animation: fadeIn 0.2s ease-in-out; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.add-ingredient-popup-container { + background-color: #ffffff; + border-radius: 20px; + padding: 40px; + width: 90%; + max-width: 400px; + position: relative; + box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.2); + animation: slideUp 0.3s ease-out; +} + +@keyframes slideUp { + from { + transform: translateY(20px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +.add-ingredient-popup-close { + position: absolute; + top: 15px; + right: 15px; + background: none; + border: none; + font-size: 32px; + color: #666666; + cursor: pointer; + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + transition: color 0.2s; +} + +.add-ingredient-popup-close:hover { + color: #000000; +} + +.add-ingredient-popup-header { + margin-bottom: 30px; + text-align: center; +} + +.add-ingredient-popup-title { + font-family: "Inter", Helvetica; + font-size: 28px; + font-weight: 700; + color: #000000; + margin: 0; +} + +.add-ingredient-popup-form { + display: flex; + flex-direction: column; + gap: 20px; +} + +.add-ingredient-popup-input-group { + display: flex; + flex-direction: column; + gap: 8px; +} + +.add-ingredient-popup-label { + font-family: "Inter", Helvetica; + font-size: 14px; + font-weight: 600; + color: #000000; +} + +.add-ingredient-popup-input, +.add-ingredient-popup-select { + padding: 12px 16px; + border: 1px solid #e0e0e0; + border-radius: 12px; + font-family: "Inter", Helvetica; + font-size: 16px; + transition: border-color 0.2s; + background-color: #ffffff; +} + +.add-ingredient-popup-input:focus, +.add-ingredient-popup-select:focus { + outline: none; + border-color: #f6910b; +} + +.add-ingredient-popup-input::placeholder { + color: #999999; +} + +.add-ingredient-popup-submit-btn { + padding: 14px; + background-color: #f6910b; + color: #ffffff; + border: none; + border-radius: 12px; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 700; + cursor: pointer; + transition: background-color 0.2s; + margin-top: 10px; +} + +.add-ingredient-popup-submit-btn:hover { + background-color: #e58209; +} diff --git a/src/components/CommunitypageWrapper/CommunitypageWrapper.jsx b/src/components/CommunitypageWrapper/CommunitypageWrapper.jsx new file mode 100644 index 0000000..8b47a5f --- /dev/null +++ b/src/components/CommunitypageWrapper/CommunitypageWrapper.jsx @@ -0,0 +1,46 @@ +/* +We're constantly improving the code you see. +Please share your feedback here: https://form.asana.com/?k=uvp-HPgd3_hyoXRBw1IcNg&d=1152665201300829 +*/ + +import React from "react"; +import { Link } from "react-router-dom"; +import "./style.css"; + +export const CommunitypageWrapper = ({ + className, + postId, + title = "돼지고기 100g 나눔합니다.", + author = "test3User", + date = "2025-11-03", + category = "나눔", + content = "" +}) => { + return ( + +
+
{category}
+
+ +
+
|
+ +
{title}
+
+ +
+
작성자 :
+ +
{author}
+ +
작성일 :
+ +
{date}
+
+ + ); +}; diff --git a/src/components/CommunitypageWrapper/index.js b/src/components/CommunitypageWrapper/index.js new file mode 100644 index 0000000..47ea4ad --- /dev/null +++ b/src/components/CommunitypageWrapper/index.js @@ -0,0 +1 @@ +export { CommunitypageWrapper } from "./CommunitypageWrapper"; diff --git a/src/components/CommunitypageWrapper/style.css b/src/components/CommunitypageWrapper/style.css new file mode 100644 index 0000000..2b8c5c0 --- /dev/null +++ b/src/components/CommunitypageWrapper/style.css @@ -0,0 +1,124 @@ +.communitypage-wrapper { + align-items: center; + border: 1px solid; + border-color: #0000001a; + border-radius: 16px; + display: flex; + gap: 10px; + padding: 2px 10px; + position: relative; + width: 100%; + text-decoration: none; +} + +.communitypage-wrapper .communitypage-6 { + align-items: center; + align-self: stretch; + display: flex; + gap: 10px; + justify-content: center; + padding: 0px 5px; + position: relative; + width: 60px; +} + +.communitypage-wrapper .communitypage-7 { + align-items: center; + align-self: stretch; + color: #000000bf; + display: flex; + flex: 1; + font-family: "Inter", Helvetica; + font-size: 20px; + font-weight: 700; + justify-content: center; + letter-spacing: -0.40px; + line-height: 24.0px; + margin-top: -1.00px; + position: relative; + text-align: center; + white-space: nowrap; +} + +.communitypage-wrapper .communitypage-8 { + align-items: center; + align-self: stretch; + display: flex; + flex: 1; + flex-grow: 1; + gap: 10px; + padding: 1px 0px; + position: relative; +} + +.communitypage-wrapper .communitypage-9 { + align-items: center; + color: #00000066; + display: flex; + font-family: "Inter", Helvetica; + font-size: 20px; + font-weight: 500; + justify-content: center; + letter-spacing: -0.40px; + line-height: 24.0px; + position: relative; + white-space: nowrap; + width: fit-content; +} + +.communitypage-wrapper .communitypage-10 { + align-items: center; + color: #000000; + display: flex; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 500; + justify-content: center; + letter-spacing: -0.32px; + line-height: 19.2px; + position: relative; + white-space: nowrap; + width: fit-content; +} + +.communitypage-wrapper .communitypage-11 { + align-items: center; + align-self: stretch; + display: flex; + flex: 1; + flex-grow: 1; + gap: 10px; + justify-content: flex-end; + padding: 3px 0px; + position: relative; +} + +.communitypage-wrapper .communitypage-12 { + align-items: center; + color: #00000066; + display: flex; + font-family: "Inter", Helvetica; + font-size: 18px; + font-weight: 500; + justify-content: center; + letter-spacing: -0.36px; + line-height: 21.6px; + margin-top: -1.00px; + position: relative; + white-space: nowrap; + width: fit-content; +} + +.communitypage-wrapper .communitypage-13 { + align-items: center; + color: #000000; + display: flex; + flex: 1; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 500; + justify-content: center; + letter-spacing: -0.32px; + line-height: 19.2px; + position: relative; +} diff --git a/src/components/DivWrapper/DivWrapper.jsx b/src/components/DivWrapper/DivWrapper.jsx new file mode 100644 index 0000000..d93923c --- /dev/null +++ b/src/components/DivWrapper/DivWrapper.jsx @@ -0,0 +1,108 @@ +/* +We're constantly improving the code you see. +Please share your feedback here: https://form.asana.com/?k=uvp-HPgd3_hyoXRBw1IcNg&d=1152665201300829 +*/ + +import React, { useState } from "react"; +import { Link } from "react-router-dom"; +import { useAuth } from "../../contexts/AuthContext"; +import { LoginPopup } from "../LoginPopup"; +import { SignupPopup } from "../SignupPopup"; +import { PreferencesPopup } from "../PreferencesPopup"; +import "./style.css"; + +export const DivWrapper = ({ className }) => { + const { user, isAuthenticated, logout } = useAuth(); + const [showLoginPopup, setShowLoginPopup] = useState(false); + const [showSignupPopup, setShowSignupPopup] = useState(false); + const [showPreferencesPopup, setShowPreferencesPopup] = useState(false); + const [userData, setUserData] = useState(null); + + const handleSwitchToSignup = () => { + setShowLoginPopup(false); + setShowSignupPopup(true); + }; + + const handleSwitchToLogin = () => { + setShowSignupPopup(false); + setShowPreferencesPopup(false); + setShowLoginPopup(true); + }; + + const handleSwitchToPreferences = (data) => { + setUserData(data); + setShowSignupPopup(false); + setShowPreferencesPopup(true); + }; + + const handleCloseAll = () => { + setShowLoginPopup(false); + setShowSignupPopup(false); + setShowPreferencesPopup(false); + setUserData(null); + }; + + return ( + <> +
+
+ + None frame + +
+ + +

+ 알고리즘 + + 셰프 +

+ + +
+ +
마이페이지
+ + {isAuthenticated ? ( +
+ {user?.username} + +
+ ) : ( + + )} +
+
+ + {showLoginPopup && ( + + )} + + {showSignupPopup && ( + + )} + + {showPreferencesPopup && ( + + )} + + ); +}; diff --git a/src/components/DivWrapper/index.js b/src/components/DivWrapper/index.js new file mode 100644 index 0000000..b316d4a --- /dev/null +++ b/src/components/DivWrapper/index.js @@ -0,0 +1 @@ +export { DivWrapper } from "./DivWrapper"; diff --git a/src/components/DivWrapper/style.css b/src/components/DivWrapper/style.css new file mode 100644 index 0000000..4e022cf --- /dev/null +++ b/src/components/DivWrapper/style.css @@ -0,0 +1,216 @@ +.div-wrapper { + align-items: center; + display: flex; + justify-content: space-between; + gap: 10px; + height: 120px; + padding: 10px; + position: relative; + width: 100%; + max-width: 1280px; +} + +.div-wrapper .header-left-section { + display: flex; + align-items: center; + flex: 1; + justify-content: flex-start; +} + +.div-wrapper .none-frame-2 { + height: 80px; + width: auto; + position: relative; +} + +.div-wrapper .algorithm-label-2-link { + display: flex; + align-items: center; + justify-content: center; + height: 100%; + position: absolute; + left: 50%; + transform: translateX(-50%); +} + +.div-wrapper .algorithm-label-2 { + align-items: center; + color: transparent; + display: flex; + font-family: "Inter", Helvetica; + font-size: 48px; + font-weight: 700; + justify-content: center; + letter-spacing: -0.96px; + line-height: 1; + margin: 0; + position: relative; + text-align: center; + width: 100%; +} + +.div-wrapper .text-wrapper-9 { + color: #000000; + letter-spacing: -0.46px; +} + +.div-wrapper .text-wrapper-10 { + color: #f6910b; + letter-spacing: -0.46px; +} + +.div-wrapper .header-right-section { + display: flex; + align-items: center; + flex: 1; + gap: 10px; + justify-content: flex-end; + padding: 10px; +} + +.div-wrapper .mypage-button-2 { + background-image: url(https://c.animaapp.com/sjWITF5i/img/loginvector-3.svg); + background-size: 100% 100%; + border: none; + border-radius: 30px; + cursor: pointer; + height: 36px; + overflow: hidden; + position: relative; + width: 120px; + transition: transform 0.2s; + text-decoration: none; + display: flex; + align-items: center; + justify-content: center; +} + +.div-wrapper .mypage-button-2:hover { + transform: scale(1.05); +} + +.div-wrapper .mypage-text-2 { + color: #ffffff; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 600; + letter-spacing: -0.32px; + line-height: 19.2px; + text-align: center; +} + +.div-wrapper .login-button-2 { + background-image: url(https://c.animaapp.com/sjWITF5i/img/loginvector-3.svg); + background-size: 100% 100%; + border: none; + border-radius: 30px; + cursor: pointer; + height: 36px; + overflow: hidden; + position: relative; + width: 120px; + transition: transform 0.2s; +} + +.div-wrapper .login-button-2:hover { + transform: scale(1.05); +} + +.div-wrapper .login-text-3 { + align-items: center; + color: #ffffff; + display: flex; + font-family: "Inter", Helvetica; + font-size: 20px; + font-weight: 600; + height: 24px; + justify-content: center; + left: calc(50.00% - 33px); + letter-spacing: -0.40px; + line-height: 24.0px; + position: absolute; + text-align: center; + top: calc(50.00% - 12px); + width: 66px; +} + +.div-wrapper .user-info-wrapper { + display: flex; + align-items: center; + gap: 10px; +} + +.div-wrapper .user-name-display { + color: #000000; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 600; + padding: 8px 16px; + background-color: #f6910b1a; + border-radius: 20px; +} + +.div-wrapper .logout-button-2 { + background-image: url(https://c.animaapp.com/sjWITF5i/img/loginvector-3.svg); + background-size: 100% 100%; + border: none; + border-radius: 30px; + cursor: pointer; + height: 36px; + overflow: hidden; + position: relative; + width: 100px; + transition: transform 0.2s; + color: #ffffff; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 600; +} + +.div-wrapper .logout-button-2:hover { + transform: scale(1.05); +} + +@media (max-width: 768px) { + .div-wrapper { + padding: 10px 5px; + height: auto; + min-height: 80px; + } + + .div-wrapper .none-frame-2 { + height: 50px; + } + + .div-wrapper .algorithm-label-2 { + font-size: 24px; + } + + .div-wrapper .mypage-button-2, + .div-wrapper .login-button-2, + .div-wrapper .logout-button-2 { + width: 90px; + height: 32px; + } + + .div-wrapper .mypage-text-2, + .div-wrapper .login-text-3 { + font-size: 12px; + } + + .div-wrapper .user-name-display { + font-size: 12px; + padding: 4px 10px; + } +} + +@media (max-width: 480px) { + .div-wrapper .algorithm-label-2 { + font-size: 20px; + } + + .div-wrapper .header-right-section { + gap: 5px; + padding: 5px; + } +} diff --git a/src/components/IngredientComponent/IngredientComponent.jsx b/src/components/IngredientComponent/IngredientComponent.jsx new file mode 100644 index 0000000..21f08e8 --- /dev/null +++ b/src/components/IngredientComponent/IngredientComponent.jsx @@ -0,0 +1,36 @@ +/* +We're constantly improving the code you see. +Please share your feedback here: https://form.asana.com/?k=uvp-HPgd3_hyoXRBw1IcNg&d=1152665201300829 +*/ + +import React from "react"; +import "./style.css"; + +export const IngredientComponent = ({ + className, + ingredientImage = "https://c.animaapp.com/sjWITF5i/img/ingredientimage-1.png", + text = "양파", + expiryDays = 0, +}) => { + return ( +
+
+
+ Ingredient image + +
+
{text}
+
+
+ +
+
유통기한 : {expiryDays}일
+
+
+
+ ); +}; diff --git a/src/components/IngredientComponent/index.js b/src/components/IngredientComponent/index.js new file mode 100644 index 0000000..b5ee1c9 --- /dev/null +++ b/src/components/IngredientComponent/index.js @@ -0,0 +1 @@ +export { IngredientComponent } from "./IngredientComponent"; diff --git a/src/components/IngredientComponent/style.css b/src/components/IngredientComponent/style.css new file mode 100644 index 0000000..c5cb482 --- /dev/null +++ b/src/components/IngredientComponent/style.css @@ -0,0 +1,107 @@ +.ingredient-component { + align-items: flex-start; + background-color: #ffffff; + border: 1px solid; + border-color: #0000001a; + border-radius: 16px; + box-shadow: 0px 12px 32px #0000000a, 0px 4px 8px #00000005; + display: flex; + flex-direction: column; + gap: 24px; + height: 120px; + justify-content: space-around; + max-height: 120px; + min-width: 140px; + overflow: hidden; + padding: 10px; + position: relative; + flex-shrink: 0; +} + +@media (max-width: 768px) { + .ingredient-component { + min-width: 120px; + } +} + +.ingredient-component .ingredient-container { + align-items: flex-start; + align-self: stretch; + display: flex; + flex: 1; + flex-direction: column; + flex-grow: 1; + justify-content: space-between; + position: relative; + width: 100%; +} + +.ingredient-component .ingredient-header { + align-items: center; + align-self: stretch; + display: flex; + flex: 0 0 auto; + gap: 10px; + position: relative; + width: 100%; +} + +.ingredient-component .ingredient-image { + aspect-ratio: 1; + height: 48px; + object-fit: cover; + position: relative; + width: 48px; +} + +.ingredient-component .ingredient-name { + align-items: center; + align-self: stretch; + display: flex; + flex: 1; + flex-grow: 1; + gap: 10px; + padding: 2px; + position: relative; +} + +.ingredient-component .ingredient-name-text { + align-items: center; + color: #000000; + display: flex; + font-family: "Inter", Helvetica; + font-size: 20px; + font-weight: 500; + justify-content: center; + letter-spacing: -0.10px; + line-height: 29.0px; + position: relative; + white-space: nowrap; + width: fit-content; +} + +.ingredient-component .ingredient { + align-items: center; + align-self: stretch; + display: flex; + flex: 1; + flex-grow: 1; + gap: 10px; + justify-content: center; + padding: 2px; + position: relative; + width: 100%; +} + +.ingredient-component .ingredient-2 { + align-self: stretch; + color: #000000; + flex: 1; + font-family: "Inter", Helvetica; + font-size: 12px; + font-weight: 500; + letter-spacing: -0.06px; + line-height: 17.4px; + margin-top: -1.00px; + position: relative; +} diff --git a/src/components/IngredientInventoryWrapper/IngredientInventoryWrapper.jsx b/src/components/IngredientInventoryWrapper/IngredientInventoryWrapper.jsx new file mode 100644 index 0000000..4162c4e --- /dev/null +++ b/src/components/IngredientInventoryWrapper/IngredientInventoryWrapper.jsx @@ -0,0 +1,19 @@ +/* +We're constantly improving the code you see. +Please share your feedback here: https://form.asana.com/?k=uvp-HPgd3_hyoXRBw1IcNg&d=1152665201300829 +*/ + +import React from "react"; +import "./style.css"; + +export const IngredientInventoryWrapper = ({ className }) => { + return ( +
+
나의 냉장고
+ +

+ 당신의 냉장고 속 재료는 무엇인가요? +

+
+ ); +}; diff --git a/src/components/IngredientInventoryWrapper/index.js b/src/components/IngredientInventoryWrapper/index.js new file mode 100644 index 0000000..9c45c63 --- /dev/null +++ b/src/components/IngredientInventoryWrapper/index.js @@ -0,0 +1 @@ +export { IngredientInventoryWrapper } from "./IngredientInventoryWrapper"; diff --git a/src/components/IngredientInventoryWrapper/style.css b/src/components/IngredientInventoryWrapper/style.css new file mode 100644 index 0000000..f07ded5 --- /dev/null +++ b/src/components/IngredientInventoryWrapper/style.css @@ -0,0 +1,56 @@ +.ingredient-inventory-wrapper { + align-items: flex-start; + border-bottom-style: solid; + border-bottom-width: 1px; + border-color: #000000; + display: flex; + flex-direction: column; + gap: 10px; + left: 64px; + padding: 5px 0px; + position: relative; + top: 25px; +} + +.ingredient-inventory-wrapper .ingredient-inventory-2 { + align-items: center; + align-self: stretch; + color: #000000; + display: flex; + font-family: "Inter", Helvetica; + font-size: 48px; + font-weight: 700; + justify-content: flex-start; + letter-spacing: -0.96px; + line-height: 57.6px; + margin-top: -1.00px; + position: relative; +} + +@media (max-width: 768px) { + .ingredient-inventory-wrapper .ingredient-inventory-2 { + font-size: 32px; + line-height: 38.4px; + } +} + +.ingredient-inventory-wrapper .ingredient-inventory-3 { + align-items: center; + align-self: stretch; + color: #0000008c; + display: flex; + font-family: "Inter", Helvetica; + font-size: 20px; + font-weight: 500; + justify-content: flex-start; + letter-spacing: -0.10px; + line-height: 29.0px; + position: relative; +} + +@media (max-width: 768px) { + .ingredient-inventory-wrapper .ingredient-inventory-3 { + font-size: 16px; + line-height: 23.2px; + } +} diff --git a/src/components/LoginPopup/LoginPopup.jsx b/src/components/LoginPopup/LoginPopup.jsx new file mode 100644 index 0000000..8d4cf23 --- /dev/null +++ b/src/components/LoginPopup/LoginPopup.jsx @@ -0,0 +1,91 @@ +import React, { useState } from "react"; +import { useAuth } from "../../contexts/AuthContext"; +import "./style.css"; + +export const LoginPopup = ({ onClose, onSwitchToSignup }) => { + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const { login } = useAuth(); + + const handleLogin = async (e) => { + e.preventDefault(); + + // TODO: Backend Integration: Replace with actual backend API call for login + // Example: axios.post('/api/login', { username, password }) + // .then(response => { + // login(response.data.user); + // onClose(); + // }) + // .catch(error => { + // alert("아이디 또는 비밀번호가 일치하지 않습니다."); + // }); + + // Simulating backend validation with localStorage + const mockUsers = JSON.parse(localStorage.getItem("registeredUsers") || "[]"); + const foundUser = mockUsers.find( + (u) => u.username === username && u.password === password + ); + + if (foundUser) { + const userData = { username: foundUser.username }; + login(userData); + console.log("Login successful:", userData); + onClose(); + } else { + alert("아이디 또는 비밀번호가 일치하지 않습니다."); + } + }; + + return ( +
+
e.stopPropagation()}> + + +
+

로그인

+
+ +
+
+ + setUsername(e.target.value)} + placeholder="아이디를 입력하세요" + required + /> +
+ +
+ + setPassword(e.target.value)} + placeholder="비밀번호를 입력하세요" + required + /> +
+ + + +
+ 계정이 없으신가요? + +
+
+
+
+ ); +}; diff --git a/src/components/LoginPopup/index.js b/src/components/LoginPopup/index.js new file mode 100644 index 0000000..369fc41 --- /dev/null +++ b/src/components/LoginPopup/index.js @@ -0,0 +1 @@ +export { LoginPopup } from "./LoginPopup"; diff --git a/src/components/LoginPopup/style.css b/src/components/LoginPopup/style.css new file mode 100644 index 0000000..4d5cd73 --- /dev/null +++ b/src/components/LoginPopup/style.css @@ -0,0 +1,162 @@ +.login-popup-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + animation: fadeIn 0.2s ease-in-out; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.login-popup-container { + background-color: #ffffff; + border-radius: 20px; + padding: 40px; + width: 90%; + max-width: 400px; + position: relative; + box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.2); + animation: slideUp 0.3s ease-out; +} + +@keyframes slideUp { + from { + transform: translateY(20px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +.login-popup-close { + position: absolute; + top: 15px; + right: 15px; + background: none; + border: none; + font-size: 32px; + color: #666666; + cursor: pointer; + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + transition: color 0.2s; +} + +.login-popup-close:hover { + color: #000000; +} + +.login-popup-header { + margin-bottom: 30px; + text-align: center; +} + +.login-popup-title { + font-family: "Inter", Helvetica; + font-size: 28px; + font-weight: 700; + color: #000000; + margin: 0; +} + +.login-popup-form { + display: flex; + flex-direction: column; + gap: 20px; +} + +.login-popup-input-group { + display: flex; + flex-direction: column; + gap: 8px; +} + +.login-popup-label { + font-family: "Inter", Helvetica; + font-size: 14px; + font-weight: 600; + color: #000000; +} + +.login-popup-input { + padding: 12px 16px; + border: 1px solid #e0e0e0; + border-radius: 12px; + font-family: "Inter", Helvetica; + font-size: 16px; + transition: border-color 0.2s; +} + +.login-popup-input:focus { + outline: none; + border-color: #f6910b; +} + +.login-popup-input::placeholder { + color: #999999; +} + +.login-popup-submit-btn { + padding: 14px; + background-color: #f6910b; + color: #ffffff; + border: none; + border-radius: 12px; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 700; + cursor: pointer; + transition: background-color 0.2s; + margin-top: 10px; +} + +.login-popup-submit-btn:hover { + background-color: #e58209; +} + +.login-popup-footer { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + margin-top: 10px; +} + +.login-popup-footer-text { + font-family: "Inter", Helvetica; + font-size: 14px; + color: #666666; +} + +.login-popup-signup-btn { + background: none; + border: none; + color: #f6910b; + font-family: "Inter", Helvetica; + font-size: 14px; + font-weight: 700; + cursor: pointer; + text-decoration: underline; +} + +.login-popup-signup-btn:hover { + color: #e58209; +} diff --git a/src/components/MenuInventoryWrapper/MenuInventoryWrapper.jsx b/src/components/MenuInventoryWrapper/MenuInventoryWrapper.jsx new file mode 100644 index 0000000..9a9a275 --- /dev/null +++ b/src/components/MenuInventoryWrapper/MenuInventoryWrapper.jsx @@ -0,0 +1,19 @@ +/* +We're constantly improving the code you see. +Please share your feedback here: https://form.asana.com/?k=uvp-HPgd3_hyoXRBw1IcNg&d=1152665201300829 +*/ + +import React from "react"; +import "./style.css"; + +export const MenuInventoryWrapper = ({ className }) => { + return ( +
+
메뉴 추천
+ +

+ 당신의 성향과 냉장고를 기반으로 메뉴를 추천해드립니다. +

+
+ ); +}; diff --git a/src/components/MenuInventoryWrapper/index.js b/src/components/MenuInventoryWrapper/index.js new file mode 100644 index 0000000..0064260 --- /dev/null +++ b/src/components/MenuInventoryWrapper/index.js @@ -0,0 +1 @@ +export { MenuInventoryWrapper } from "./MenuInventoryWrapper"; diff --git a/src/components/MenuInventoryWrapper/style.css b/src/components/MenuInventoryWrapper/style.css new file mode 100644 index 0000000..0ca8d78 --- /dev/null +++ b/src/components/MenuInventoryWrapper/style.css @@ -0,0 +1,55 @@ +.menu-inventory-wrapper { + align-items: flex-start; + border-bottom-style: solid; + border-bottom-width: 1px; + border-color: #000000; + display: flex; + flex-direction: column; + gap: 10px; + left: 64px; + padding: 5px 0px; + position: relative; + top: 25px; + width: 1152px; +} + +.menu-inventory-wrapper .menu-inventory-label { + align-items: center; + align-self: stretch; + color: #000000; + display: flex; + font-family: "Inter", Helvetica; + font-size: 48px; + font-weight: 700; + justify-content: flex-start; + letter-spacing: -0.96px; + line-height: 57.6px; + margin-top: -1.00px; + position: relative; +} + +.menu-inventory-wrapper .menu-inventory-2 { + align-items: center; + align-self: stretch; + color: #0000008c; + display: flex; + font-family: "Inter", Helvetica; + font-size: 20px; + font-weight: 500; + justify-content: flex-start; + letter-spacing: -0.10px; + line-height: 29.0px; + position: relative; +} + +@media (max-width: 768px) { + .menu-inventory-wrapper .menu-inventory-label { + font-size: 32px; + line-height: 38.4px; + } + + .menu-inventory-wrapper .menu-inventory-2 { + font-size: 16px; + line-height: 23.2px; + } +} diff --git a/src/components/MypageTendency/MypageTendency.jsx b/src/components/MypageTendency/MypageTendency.jsx new file mode 100644 index 0000000..8f03892 --- /dev/null +++ b/src/components/MypageTendency/MypageTendency.jsx @@ -0,0 +1,19 @@ +/* +We're constantly improving the code you see. +Please share your feedback here: https://form.asana.com/?k=uvp-HPgd3_hyoXRBw1IcNg&d=1152665201300829 +*/ + +import React from "react"; +import "./style.css"; + +export const MypageTendency = ({ className, text = "매콤칼칼" }) => { + return ( +
+
+
+
{text}
+
+
+
+ ); +}; diff --git a/src/components/MypageTendency/index.js b/src/components/MypageTendency/index.js new file mode 100644 index 0000000..ccc46e0 --- /dev/null +++ b/src/components/MypageTendency/index.js @@ -0,0 +1 @@ +export { MypageTendency } from "./MypageTendency"; diff --git a/src/components/MypageTendency/style.css b/src/components/MypageTendency/style.css new file mode 100644 index 0000000..079a288 --- /dev/null +++ b/src/components/MypageTendency/style.css @@ -0,0 +1,55 @@ +.mypage-tendency { + align-items: center; + background-color: #f6910b; + border: 1px solid; + border-color: #0000001a; + border-radius: 16px; + box-shadow: 0px 6px 12px #00000008, 0px 4px 8px #00000005; + display: inline-flex; + flex-direction: column; + min-height: 40px; + justify-content: center; + overflow: hidden; + position: relative; + padding: 8px 16px; +} + +.mypage-tendency .tendency-name-wrapper { + align-items: flex-start; + align-self: stretch; + display: flex; + flex: 1; + flex-direction: column; + flex-grow: 1; + justify-content: center; + padding: 2px 10px; + position: relative; + width: 100%; +} + +.mypage-tendency .tendency-name-text-wrapper { + align-items: flex-start; + align-self: stretch; + display: flex; + flex: 0 0 auto; + flex-direction: column; + position: relative; + width: 100%; +} + +.mypage-tendency .tendency-name-text-2 { + align-items: center; + align-self: stretch; + color: #ffffff; + display: flex; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 700; + justify-content: center; + letter-spacing: -0.08px; + line-height: 22.4px; + margin: 0; + position: relative; + text-align: center; + white-space: nowrap; +} diff --git a/src/components/PageButton/PageButton.jsx b/src/components/PageButton/PageButton.jsx new file mode 100644 index 0000000..65c6620 --- /dev/null +++ b/src/components/PageButton/PageButton.jsx @@ -0,0 +1,18 @@ +/* +We're constantly improving the code you see. +Please share your feedback here: https://form.asana.com/?k=uvp-HPgd3_hyoXRBw1IcNg&d=1152665201300829 +*/ + +import React from "react"; +import "./style.css"; + +export const PageButton = ({ className, text = "1", isActive = false, onClick }) => { + return ( + + ); +}; diff --git a/src/components/PageButton/index.js b/src/components/PageButton/index.js new file mode 100644 index 0000000..b4b7bf5 --- /dev/null +++ b/src/components/PageButton/index.js @@ -0,0 +1 @@ +export { PageButton } from "./PageButton"; diff --git a/src/components/PageButton/style.css b/src/components/PageButton/style.css new file mode 100644 index 0000000..37f0754 --- /dev/null +++ b/src/components/PageButton/style.css @@ -0,0 +1,46 @@ +.page-button { + align-items: center; + background: none; + border: none; + border-bottom-style: solid; + border-bottom-width: 1px; + border-color: #00000033; + cursor: pointer; + display: flex; + flex-direction: column; + height: 20px; + justify-content: center; + position: relative; + width: 20px; + transition: border-color 0.2s; +} + +.page-button:hover { + border-color: #000000cc; +} + +.page-button.active { + border-color: #f6910b; +} + +.page-button .element { + align-items: center; + align-self: stretch; + color: #000000; + display: flex; + font-family: "Inter", Helvetica; + font-size: 15px; + font-weight: 600; + height: 17px; + justify-content: center; + letter-spacing: -0.30px; + line-height: 18.0px; + position: relative; + text-align: center; + white-space: nowrap; + transition: color 0.2s; +} + +.page-button.active .element { + color: #f6910b; +} diff --git a/src/components/PreferencesPopup/PreferencesPopup.jsx b/src/components/PreferencesPopup/PreferencesPopup.jsx new file mode 100644 index 0000000..924c41f --- /dev/null +++ b/src/components/PreferencesPopup/PreferencesPopup.jsx @@ -0,0 +1,217 @@ +import React, { useState } from "react"; +import "./style.css"; + +const HEALTH_GOALS = [ + { id: 1, name: "체중 감량" }, + { id: 2, name: "근육 증가" }, + { id: 3, name: "건강 유지" }, + { id: 4, name: "면역력 강화" }, + { id: 5, name: "소화 개선" }, +]; + +const ALLERGIES = [ + { id: 1, name: "우유" }, + { id: 2, name: "계란" }, + { id: 3, name: "땅콩" }, + { id: 4, name: "견과류" }, + { id: 5, name: "갑각류" }, + { id: 6, name: "밀" }, + { id: 7, name: "대두" }, +]; + +const SPICE_LEVELS = ["안매움", "약간매움", "매움", "아주매움"]; +const CUISINE_TYPES = ["한식", "중식", "일식", "양식", "기타"]; + +export const PreferencesPopup = ({ onClose, userData }) => { + const [healthGoalIds, setHealthGoalIds] = useState([]); + const [allergyIds, setAllergyIds] = useState([]); + const [dislikedIngredients, setDislikedIngredients] = useState(""); + const [preferredIngredients, setPreferredIngredients] = useState(""); + const [preferredCuisine, setPreferredCuisine] = useState(""); + const [spiceLevel, setSpiceLevel] = useState(""); + const [allowPushConsumption, setAllowPushConsumption] = useState(true); + const [allowPushComment, setAllowPushComment] = useState(true); + const [allowPushNudge, setAllowPushNudge] = useState(true); + + const toggleHealthGoal = (id) => { + setHealthGoalIds((prev) => + prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id] + ); + }; + + const toggleAllergy = (id) => { + setAllergyIds((prev) => + prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id] + ); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + + const preferences = { + ...userData, + healthGoalIds, + allergyIds, + dislikedIngredients, + preferredIngredients, + preferredCuisine, + spiceLevel, + allowPushConsumption, + allowPushComment, + allowPushNudge, + }; + + // TODO: Backend Integration: Replace with actual API call to save user preferences + // Example: axios.post(`/api/users/${userData.username}/preferences`, preferences) + // .then(() => { + // alert("회원가입이 완료되었습니다!"); + // onClose(); + // }) + // .catch(error => { + // alert("성향 저장 실패: " + error.response.data.message); + // }); + + // Simulating saving preferences to localStorage + console.log("Complete signup with preferences:", preferences); + localStorage.setItem("userPreferences", JSON.stringify(preferences)); // Store preferences + alert("회원가입이 완료되었습니다!"); + onClose(); + }; + + return ( +
+
e.stopPropagation()}> + + +
+

성향 설정

+

맞춤 추천을 위한 정보를 입력해주세요

+
+ +
+
+ +
+ {HEALTH_GOALS.map((goal) => ( + + ))} +
+
+ +
+ +
+ {ALLERGIES.map((allergy) => ( + + ))} +
+
+ +
+ + setDislikedIngredients(e.target.value)} + placeholder="예: 오이, 가지" + /> +
+ +
+ + setPreferredIngredients(e.target.value)} + placeholder="예: 돼지고기, 감자" + /> +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ + + +
+
+ + +
+
+
+ ); +}; diff --git a/src/components/PreferencesPopup/index.js b/src/components/PreferencesPopup/index.js new file mode 100644 index 0000000..d571f4a --- /dev/null +++ b/src/components/PreferencesPopup/index.js @@ -0,0 +1 @@ +export { PreferencesPopup } from "./PreferencesPopup"; diff --git a/src/components/PreferencesPopup/style.css b/src/components/PreferencesPopup/style.css new file mode 100644 index 0000000..f313960 --- /dev/null +++ b/src/components/PreferencesPopup/style.css @@ -0,0 +1,193 @@ +.preferences-popup-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + animation: fadeIn 0.2s ease-in-out; +} + +.preferences-popup-container { + background-color: #ffffff; + border-radius: 20px; + padding: 40px; + width: 90%; + max-width: 600px; + max-height: 90vh; + overflow-y: auto; + position: relative; + box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.2); + animation: slideUp 0.3s ease-out; +} + +.preferences-popup-close { + position: absolute; + top: 15px; + right: 15px; + background: none; + border: none; + font-size: 32px; + color: #666666; + cursor: pointer; + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + transition: color 0.2s; + z-index: 1; +} + +.preferences-popup-close:hover { + color: #000000; +} + +.preferences-popup-header { + margin-bottom: 30px; + text-align: center; +} + +.preferences-popup-title { + font-family: "Inter", Helvetica; + font-size: 28px; + font-weight: 700; + color: #000000; + margin: 0 0 10px 0; +} + +.preferences-popup-subtitle { + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 500; + color: #666666; + margin: 0; +} + +.preferences-popup-form { + display: flex; + flex-direction: column; + gap: 25px; +} + +.preferences-popup-section { + display: flex; + flex-direction: column; + gap: 12px; +} + +.preferences-popup-section-label { + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 700; + color: #000000; +} + +.preferences-popup-chips { + display: flex; + flex-wrap: wrap; + gap: 10px; +} + +.preferences-chip { + padding: 8px 16px; + background-color: #e0e0e0; + border: 2px solid transparent; + border-radius: 20px; + color: #666666; + cursor: pointer; + font-family: "Inter", Helvetica; + font-size: 14px; + font-weight: 600; + transition: all 0.2s; +} + +.preferences-chip:hover { + background-color: #d0d0d0; +} + +.preferences-chip.active { + background-color: #f6910b; + border-color: #f6910b; + color: #ffffff; +} + +.preferences-popup-input-group { + display: flex; + flex-direction: column; + gap: 8px; +} + +.preferences-popup-label { + font-family: "Inter", Helvetica; + font-size: 14px; + font-weight: 600; + color: #000000; +} + +.preferences-popup-input, +.preferences-popup-select { + padding: 12px 16px; + border: 1px solid #e0e0e0; + border-radius: 12px; + font-family: "Inter", Helvetica; + font-size: 16px; + transition: border-color 0.2s; + background-color: #ffffff; +} + +.preferences-popup-input:focus, +.preferences-popup-select:focus { + outline: none; + border-color: #f6910b; +} + +.preferences-popup-input::placeholder { + color: #999999; +} + +.preferences-popup-checkboxes { + display: flex; + flex-direction: column; + gap: 12px; +} + +.preferences-checkbox-label { + display: flex; + align-items: center; + gap: 10px; + cursor: pointer; + font-family: "Inter", Helvetica; + font-size: 14px; + font-weight: 500; + color: #000000; +} + +.preferences-checkbox-label input[type="checkbox"] { + width: 20px; + height: 20px; + cursor: pointer; + accent-color: #f6910b; +} + +.preferences-popup-submit-btn { + padding: 14px; + background-color: #f6910b; + color: #ffffff; + border: none; + border-radius: 12px; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 700; + cursor: pointer; + transition: background-color 0.2s; + margin-top: 10px; +} + +.preferences-popup-submit-btn:hover { + background-color: #e58209; +} diff --git a/src/components/Recipepage/Recipepage.jsx b/src/components/Recipepage/Recipepage.jsx new file mode 100644 index 0000000..df0a519 --- /dev/null +++ b/src/components/Recipepage/Recipepage.jsx @@ -0,0 +1,15 @@ +/* +We're constantly improving the code you see. +Please share your feedback here: https://form.asana.com/?k=uvp-HPgd3_hyoXRBw1IcNg&d=1152665201300829 +*/ + +import React from "react"; +import "./style.css"; + +export const Recipepage = ({ className, text = "닭고기" }) => { + return ( +
+
{text}
+
+ ); +}; diff --git a/src/components/Recipepage/index.js b/src/components/Recipepage/index.js new file mode 100644 index 0000000..8a0ee11 --- /dev/null +++ b/src/components/Recipepage/index.js @@ -0,0 +1 @@ +export { Recipepage } from "./Recipepage"; diff --git a/src/components/Recipepage/style.css b/src/components/Recipepage/style.css new file mode 100644 index 0000000..0ffc920 --- /dev/null +++ b/src/components/Recipepage/style.css @@ -0,0 +1,31 @@ +.recipepage { + align-items: center; + border: 1px solid; + border-color: #0000001a; + border-radius: 16px; + display: inline-flex; + flex-direction: column; + gap: 10px; + justify-content: center; + left: 10px; + padding: 5px 15px; + position: relative; + top: 10px; +} + +.recipepage .text-wrapper-11 { + align-items: center; + color: #000000cc; + display: flex; + font-family: "Inter", Helvetica; + font-size: 24px; + font-weight: 500; + justify-content: center; + letter-spacing: -0.12px; + line-height: 33.6px; + margin-top: -1.00px; + position: relative; + text-align: center; + white-space: nowrap; + width: fit-content; +} diff --git a/src/components/SignupPopup/SignupPopup.jsx b/src/components/SignupPopup/SignupPopup.jsx new file mode 100644 index 0000000..6e93d5e --- /dev/null +++ b/src/components/SignupPopup/SignupPopup.jsx @@ -0,0 +1,150 @@ +import React, { useState } from "react"; +import "./style.css"; + +export const SignupPopup = ({ onClose, onSwitchToLogin, onSwitchToPreferences }) => { + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + const [email, setEmail] = useState(""); + const [gender, setGender] = useState(""); + const [birthDate, setBirthDate] = useState(""); + + const handleSignup = (e) => { + e.preventDefault(); + + if (password !== confirmPassword) { + alert("비밀번호가 일치하지 않습니다."); + return; + } + + // TODO: Backend Integration: Replace with actual backend API call for signup + // Example: axios.post('/api/signup', userData) + // .then(response => { + // onSwitchToPreferences(response.data.user); // Pass user data from backend + // }) + // .catch(error => { + // alert("회원가입 실패: " + error.response.data.message); + // }); + + // Simulating backend validation and storage with localStorage + const mockUsers = JSON.parse(localStorage.getItem("registeredUsers") || "[]"); + + // Check if username already exists + if (mockUsers.find((u) => u.username === username)) { + alert("이미 존재하는 아이디입니다."); + return; + } + + const userData = { username, email, password, gender, birthDate }; + mockUsers.push(userData); + localStorage.setItem("registeredUsers", JSON.stringify(mockUsers)); + + console.log("Signup attempt:", userData); + + // Move to preferences popup + onSwitchToPreferences(userData); + }; + + return ( +
+
e.stopPropagation()}> + + +
+

회원가입

+
+ +
+
+ + setUsername(e.target.value)} + placeholder="아이디를 입력하세요" + required + /> +
+ +
+ + setEmail(e.target.value)} + placeholder="이메일을 입력하세요" + required + /> +
+ +
+ + setPassword(e.target.value)} + placeholder="비밀번호를 입력하세요" + required + /> +
+ +
+ + setConfirmPassword(e.target.value)} + placeholder="비밀번호를 다시 입력하세요" + required + /> +
+ +
+ + +
+ +
+ + setBirthDate(e.target.value)} + required + /> +
+ + + +
+ 이미 계정이 있으신가요? + +
+
+
+
+ ); +}; diff --git a/src/components/SignupPopup/index.js b/src/components/SignupPopup/index.js new file mode 100644 index 0000000..de7e73a --- /dev/null +++ b/src/components/SignupPopup/index.js @@ -0,0 +1 @@ +export { SignupPopup } from "./SignupPopup"; diff --git a/src/components/SignupPopup/style.css b/src/components/SignupPopup/style.css new file mode 100644 index 0000000..92d1b00 --- /dev/null +++ b/src/components/SignupPopup/style.css @@ -0,0 +1,167 @@ +.signup-popup-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + animation: fadeIn 0.2s ease-in-out; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.signup-popup-container { + background-color: #ffffff; + border-radius: 20px; + padding: 40px; + width: 90%; + max-width: 400px; + position: relative; + box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.2); + animation: slideUp 0.3s ease-out; + max-height: 90vh; + overflow-y: auto; +} + +@keyframes slideUp { + from { + transform: translateY(20px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +.signup-popup-close { + position: absolute; + top: 15px; + right: 15px; + background: none; + border: none; + font-size: 32px; + color: #666666; + cursor: pointer; + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + transition: color 0.2s; +} + +.signup-popup-close:hover { + color: #000000; +} + +.signup-popup-header { + margin-bottom: 30px; + text-align: center; +} + +.signup-popup-title { + font-family: "Inter", Helvetica; + font-size: 28px; + font-weight: 700; + color: #000000; + margin: 0; +} + +.signup-popup-form { + display: flex; + flex-direction: column; + gap: 20px; +} + +.signup-popup-input-group { + display: flex; + flex-direction: column; + gap: 8px; +} + +.signup-popup-label { + font-family: "Inter", Helvetica; + font-size: 14px; + font-weight: 600; + color: #000000; +} + +.signup-popup-input, +.signup-popup-select { + padding: 12px 16px; + border: 1px solid #e0e0e0; + border-radius: 12px; + font-family: "Inter", Helvetica; + font-size: 16px; + transition: border-color 0.2s; + background-color: #ffffff; +} + +.signup-popup-input:focus, +.signup-popup-select:focus { + outline: none; + border-color: #f6910b; +} + +.signup-popup-input::placeholder { + color: #999999; +} + +.signup-popup-submit-btn { + padding: 14px; + background-color: #f6910b; + color: #ffffff; + border: none; + border-radius: 12px; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 700; + cursor: pointer; + transition: background-color 0.2s; + margin-top: 10px; +} + +.signup-popup-submit-btn:hover { + background-color: #e58209; +} + +.signup-popup-footer { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + margin-top: 10px; +} + +.signup-popup-footer-text { + font-family: "Inter", Helvetica; + font-size: 14px; + color: #666666; +} + +.signup-popup-login-btn { + background: none; + border: none; + color: #f6910b; + font-family: "Inter", Helvetica; + font-size: 14px; + font-weight: 700; + cursor: pointer; + text-decoration: underline; +} + +.signup-popup-login-btn:hover { + color: #e58209; +} diff --git a/src/components/Tendency/Tendency.jsx b/src/components/Tendency/Tendency.jsx new file mode 100644 index 0000000..951a804 --- /dev/null +++ b/src/components/Tendency/Tendency.jsx @@ -0,0 +1,22 @@ +/* +We're constantly improving the code you see. +Please share your feedback here: https://form.asana.com/?k=uvp-HPgd3_hyoXRBw1IcNg&d=1152665201300829 +*/ + +import React from "react"; +import "./style.css"; + +export const Tendency = ({ tendencyContainerClassName, text = "매콤칼칼", isActive = false, onClick }) => { + return ( + + ); +}; diff --git a/src/components/Tendency/index.js b/src/components/Tendency/index.js new file mode 100644 index 0000000..4ba92b2 --- /dev/null +++ b/src/components/Tendency/index.js @@ -0,0 +1 @@ +export { Tendency } from "./Tendency"; diff --git a/src/components/Tendency/style.css b/src/components/Tendency/style.css new file mode 100644 index 0000000..b02e42c --- /dev/null +++ b/src/components/Tendency/style.css @@ -0,0 +1,70 @@ +.tendency { + align-items: center; + background-color: #e0e0e0; + border: 1px solid; + border-color: #0000001a; + border-radius: 16px; + box-shadow: 0px 6px 12px #00000008, 0px 4px 8px #00000005; + cursor: pointer; + display: inline-flex; + justify-content: center; + overflow: hidden; + padding: 6px 16px; + position: relative; + transition: all 0.2s ease; + min-width: fit-content; +} + +.tendency:hover { + transform: translateY(-2px); + box-shadow: 0px 8px 16px #00000012, 0px 6px 10px #00000008; +} + +.tendency.tendency-active { + background-color: #f6910b; +} + +.tendency .tendency-container { + align-items: center; + display: inline-flex; + flex-direction: column; + justify-content: center; + position: relative; +} + +.tendency .tendency-name { + align-items: center; + display: inline-flex; + flex-direction: column; + justify-content: center; + position: relative; +} + +.tendency .tendency-name-text { + align-items: center; + color: #666666; + display: flex; + font-family: "Inter", Helvetica; + font-size: 12px; + font-weight: 700; + justify-content: center; + letter-spacing: -0.06px; + line-height: 16.8px; + text-align: center; + white-space: nowrap; + transition: color 0.2s ease; +} + +.tendency.tendency-active .tendency-name-text { + color: #ffffff; +} + +@media (max-width: 768px) { + .tendency { + padding: 5px 12px; + } + + .tendency .tendency-name-text { + font-size: 11px; + } +} diff --git a/src/components/UnifiedHeader/UnifiedHeader.jsx b/src/components/UnifiedHeader/UnifiedHeader.jsx new file mode 100644 index 0000000..c3173d2 --- /dev/null +++ b/src/components/UnifiedHeader/UnifiedHeader.jsx @@ -0,0 +1,125 @@ +import React, { useState } from "react"; +import { Link } from "react-router-dom"; +import { useAuth } from "../../contexts/AuthContext"; +import { LoginPopup } from "../LoginPopup"; +import { SignupPopup } from "../SignupPopup"; +import { PreferencesPopup } from "../PreferencesPopup"; +import "./style.css"; + +export const UnifiedHeader = () => { + const { user, isAuthenticated, logout } = useAuth(); + const [showLoginPopup, setShowLoginPopup] = useState(false); + const [showSignupPopup, setShowSignupPopup] = useState(false); + const [showPreferencesPopup, setShowPreferencesPopup] = useState(false); + const [showMenu, setShowMenu] = useState(false); + const [userData, setUserData] = useState(null); + + const handleSwitchToSignup = () => { + setShowLoginPopup(false); + setShowSignupPopup(true); + }; + + const handleSwitchToLogin = () => { + setShowSignupPopup(false); + setShowPreferencesPopup(false); + setShowLoginPopup(true); + }; + + const handleSwitchToPreferences = (data) => { + setUserData(data); + setShowSignupPopup(false); + setShowPreferencesPopup(true); + }; + + const handleCloseAll = () => { + setShowLoginPopup(false); + setShowSignupPopup(false); + setShowPreferencesPopup(false); + setUserData(null); + }; + + return ( + <> +
+
+ + {showMenu && ( +
+ setShowMenu(false)}> + 홈 + + setShowMenu(false)}> + 메뉴 추천 + + setShowMenu(false)}> + 재료 나눔 게시판 + + setShowMenu(false)}> + 마이페이지 + +
+ )} + + Logo + +
+ + +

+ 알고리즘 + 셰프 +

+ + +
+ +
마이페이지
+ + {isAuthenticated ? ( +
+ {user?.username} + +
+ ) : ( + + )} +
+
+ + {showLoginPopup && ( + + )} + + {showSignupPopup && ( + + )} + + {showPreferencesPopup && ( + + )} + + ); +}; diff --git a/src/components/UnifiedHeader/index.js b/src/components/UnifiedHeader/index.js new file mode 100644 index 0000000..cab05e2 --- /dev/null +++ b/src/components/UnifiedHeader/index.js @@ -0,0 +1 @@ +export { UnifiedHeader } from "./UnifiedHeader"; diff --git a/src/components/UnifiedHeader/style.css b/src/components/UnifiedHeader/style.css new file mode 100644 index 0000000..af3725a --- /dev/null +++ b/src/components/UnifiedHeader/style.css @@ -0,0 +1,268 @@ +.unified-header { + align-items: center; + background-color: transparent; + display: flex; + justify-content: space-between; + gap: 10px; + height: 120px; + padding: 10px 20px; + position: relative; + width: 100%; + max-width: 1280px; + margin: 0 auto; +} + +.unified-header-left { + display: flex; + align-items: center; + gap: 15px; + flex: 1; + justify-content: flex-start; + position: relative; +} + +.menu-toggle-btn { + background: none; + border: none; + font-size: 28px; + color: #000000; + cursor: pointer; + padding: 5px 10px; + transition: color 0.2s; +} + +.menu-toggle-btn:hover { + color: #f6910b; +} + +.menu-dropdown { + position: absolute; + top: 100%; + left: 0; + margin-top: 10px; + background-color: #ffffff; + border: 1px solid #e0e0e0; + border-radius: 12px; + box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1); + overflow: hidden; + z-index: 100; + min-width: 200px; +} + +.menu-item { + display: block; + padding: 15px 20px; + color: #000000; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 500; + text-decoration: none; + transition: background-color 0.2s; + border-bottom: 1px solid #f0f0f0; +} + +.menu-item:last-child { + border-bottom: none; +} + +.menu-item:hover { + background-color: #f6910b1a; + color: #f6910b; +} + +.unified-header-logo { + height: 80px; + width: auto; + display: block; +} + +.unified-header-center { + position: absolute; + left: 50%; + transform: translateX(-50%); + display: flex; + align-items: center; + height: 100%; + text-decoration: none; +} + +.unified-header-title { + align-items: center; + color: transparent; + display: flex; + font-family: "Inter", Helvetica; + font-size: 48px; + font-weight: 700; + justify-content: center; + letter-spacing: -0.96px; + line-height: 1; + margin: 0; + text-align: center; +} + +.title-text-black { + color: #000000; + letter-spacing: -0.46px; +} + +.title-text-orange { + color: #f6910b; + letter-spacing: -0.46px; +} + +.unified-header-right { + display: flex; + align-items: center; + flex: 1; + gap: 10px; + justify-content: flex-end; +} + +.unified-mypage-btn { + background-image: url(https://c.animaapp.com/sjWITF5i/img/loginvector-3.svg); + background-size: 100% 100%; + border: none; + border-radius: 30px; + cursor: pointer; + height: 36px; + overflow: hidden; + position: relative; + width: 120px; + transition: transform 0.2s; + text-decoration: none; + display: flex; + align-items: center; + justify-content: center; +} + +.unified-mypage-btn:hover { + transform: scale(1.05); +} + +.unified-mypage-text { + color: #ffffff; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 600; + letter-spacing: -0.32px; + line-height: 19.2px; + text-align: center; +} + +.unified-login-btn { + background-image: url(https://c.animaapp.com/sjWITF5i/img/loginvector-3.svg); + background-size: 100% 100%; + border: none; + border-radius: 30px; + cursor: pointer; + height: 36px; + overflow: hidden; + position: relative; + width: 120px; + transition: transform 0.2s; +} + +.unified-login-btn:hover { + transform: scale(1.05); +} + +.unified-login-text { + align-items: center; + color: #ffffff; + display: flex; + font-family: "Inter", Helvetica; + font-size: 20px; + font-weight: 600; + height: 24px; + justify-content: center; + left: calc(50.00% - 33px); + letter-spacing: -0.40px; + line-height: 24.0px; + position: absolute; + text-align: center; + top: calc(50.00% - 12px); + width: 66px; +} + +.unified-user-info { + display: flex; + align-items: center; + gap: 10px; +} + +.unified-username { + color: #000000; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 600; + padding: 8px 16px; + background-color: #f6910b1a; + border-radius: 20px; +} + +.unified-logout-btn { + background-image: url(https://c.animaapp.com/sjWITF5i/img/loginvector-3.svg); + background-size: 100% 100%; + border: none; + border-radius: 30px; + cursor: pointer; + height: 36px; + padding: 0 20px; + position: relative; + transition: transform 0.2s; + color: #ffffff; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 600; +} + +.unified-logout-btn:hover { + transform: scale(1.05); +} + +@media (max-width: 768px) { + .unified-header { + padding: 10px 10px; + height: auto; + min-height: 80px; + } + + .unified-header-logo { + height: 50px; + } + + .unified-header-title { + font-size: 24px; + } + + .unified-mypage-btn, + .unified-login-btn, + .unified-logout-btn { + width: 90px; + height: 32px; + } + + .unified-mypage-text, + .unified-login-text { + font-size: 12px; + } + + .unified-username { + font-size: 12px; + padding: 4px 10px; + } + + .menu-toggle-btn { + font-size: 24px; + } +} + +@media (max-width: 480px) { + .unified-header-title { + font-size: 20px; + } + + .unified-header-right { + gap: 5px; + } +} diff --git a/src/components/UsedIngredient/UsedIngredient.jsx b/src/components/UsedIngredient/UsedIngredient.jsx new file mode 100644 index 0000000..24ef221 --- /dev/null +++ b/src/components/UsedIngredient/UsedIngredient.jsx @@ -0,0 +1,15 @@ +/* +We're constantly improving the code you see. +Please share your feedback here: https://form.asana.com/?k=uvp-HPgd3_hyoXRBw1IcNg&d=1152665201300829 +*/ + +import React from "react"; +import "./style.css"; + +export const UsedIngredient = ({ className, text = "닭고기" }) => { + return ( +
+
{text}
+
+ ); +}; diff --git a/src/components/UsedIngredient/index.js b/src/components/UsedIngredient/index.js new file mode 100644 index 0000000..fc3b90e --- /dev/null +++ b/src/components/UsedIngredient/index.js @@ -0,0 +1 @@ +export { UsedIngredient } from "./UsedIngredient"; diff --git a/src/components/UsedIngredient/style.css b/src/components/UsedIngredient/style.css new file mode 100644 index 0000000..0ce632e --- /dev/null +++ b/src/components/UsedIngredient/style.css @@ -0,0 +1,32 @@ +.used-ingredient { + align-items: center; + border: 1px solid; + border-color: #0000001a; + border-radius: 16px; + display: inline-flex; + flex-direction: column; + gap: 10px; + height: 23px; + justify-content: center; + left: 4px; + padding: 3px 10px; + position: relative; + top: 2px; +} + +.used-ingredient .use-ingredient-name { + align-items: center; + color: #000000cc; + display: flex; + font-family: "Inter", Helvetica; + font-size: 12px; + font-weight: 500; + justify-content: center; + letter-spacing: -0.06px; + line-height: 16.8px; + margin-top: -1.00px; + position: relative; + text-align: center; + white-space: nowrap; + width: fit-content; +} diff --git a/src/contexts/AuthContext.js b/src/contexts/AuthContext.js new file mode 100644 index 0000000..328bb52 --- /dev/null +++ b/src/contexts/AuthContext.js @@ -0,0 +1 @@ +export { AuthProvider, useAuth } from "./AuthContext.jsx"; diff --git a/src/contexts/AuthContext.jsx b/src/contexts/AuthContext.jsx new file mode 100644 index 0000000..930af19 --- /dev/null +++ b/src/contexts/AuthContext.jsx @@ -0,0 +1,44 @@ +import React, { createContext, useContext, useState, useEffect } from "react"; + +const AuthContext = createContext(); + +export const useAuth = () => { + const context = useContext(AuthContext); + if (!context) { + throw new Error("useAuth must be used within an AuthProvider"); + } + return context; +}; + +export const AuthProvider = ({ children }) => { + const [user, setUser] = useState(null); + const [isAuthenticated, setIsAuthenticated] = useState(false); + + useEffect(() => { + // Check if user is logged in from localStorage + const storedUser = localStorage.getItem("currentUser"); + if (storedUser) { + const userData = JSON.parse(storedUser); + setUser(userData); + setIsAuthenticated(true); + } + }, []); + + const login = (userData) => { + setUser(userData); + setIsAuthenticated(true); + localStorage.setItem("currentUser", JSON.stringify(userData)); + }; + + const logout = () => { + setUser(null); + setIsAuthenticated(false); + localStorage.removeItem("currentUser"); + }; + + return ( + + {children} + + ); +}; diff --git a/src/index.css b/src/index.css deleted file mode 100644 index 08a3ac9..0000000 --- a/src/index.css +++ /dev/null @@ -1,68 +0,0 @@ -:root { - font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/src/index.jsx b/src/index.jsx new file mode 100644 index 0000000..f55d523 --- /dev/null +++ b/src/index.jsx @@ -0,0 +1,9 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import { App } from "./App"; + +createRoot(document.getElementById("app")).render( + + + , +); diff --git a/src/main.jsx b/src/main.jsx deleted file mode 100644 index b9a1a6d..0000000 --- a/src/main.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import './index.css' -import App from './App.jsx' - -createRoot(document.getElementById('root')).render( - - - , -) diff --git a/src/screens/AddIngredientPage/AddIngredientPage.jsx b/src/screens/AddIngredientPage/AddIngredientPage.jsx new file mode 100644 index 0000000..19f69ce --- /dev/null +++ b/src/screens/AddIngredientPage/AddIngredientPage.jsx @@ -0,0 +1,133 @@ +import React, { useState } from "react"; +import { Link, useNavigate } from "react-router-dom"; +import { UnifiedHeader } from "../../components/UnifiedHeader"; +import "./style.css"; + +const CATEGORIES = ["전체", "육류", "채소류", "가공류", "유제품", "기타"]; + +const MOCK_INGREDIENT_DATABASE = [ + // TODO: Backend Integration: Replace with API call to fetch all available ingredients from DB + { id: 1, name: "양파", category: "채소류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-1.png" }, + { id: 2, name: "닭고기", category: "육류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 3, name: "돼지고기", category: "육류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 4, name: "소고기", category: "육류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 5, name: "고추장", category: "가공류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 6, name: "고춧가루", category: "가공류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 7, name: "된장", category: "가공류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 8, name: "간장", category: "가공류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 9, name: "양배추", category: "채소류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 10, name: "당근", category: "채소류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 11, name: "감자", category: "채소류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 12, name: "마늘", category: "채소류", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 13, name: "우유", category: "유제품", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 14, name: "치즈", category: "유제품", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 15, name: "요거트", category: "유제품", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, + { id: 16, name: "계란", category: "기타", image: "https://c.animaapp.com/sjWITF5i/img/ingredientimage-7@2x.png" }, +]; + +export const AddIngredientPage = () => { + const navigate = useNavigate(); + const [selectedCategory, setSelectedCategory] = useState("전체"); + const [searchQuery, setSearchQuery] = useState(""); + const [selectedIngredients, setSelectedIngredients] = useState([]); + + const filteredIngredients = MOCK_INGREDIENT_DATABASE.filter((ingredient) => { + const matchesCategory = selectedCategory === "전체" || ingredient.category === selectedCategory; + const matchesSearch = ingredient.name.toLowerCase().includes(searchQuery.toLowerCase()); + return matchesCategory && matchesSearch; + }); + + const toggleIngredient = (ingredient) => { + setSelectedIngredients((prev) => { + const exists = prev.find((item) => item.id === ingredient.id); + if (exists) { + return prev.filter((item) => item.id !== ingredient.id); + } else { + return [...prev, { ...ingredient, expiryDays: 7 }]; + } + }); + }; + + const handleAddIngredients = () => { + // TODO: Send selected ingredients to backend + console.log("Adding ingredients:", selectedIngredients); + navigate("/desktop"); + }; + + return ( +
+ + +
+
+

식재료 추가

+

냉장고에 추가할 식재료를 선택하세요

+
+ +
+ setSearchQuery(e.target.value)} + /> +
+ +
+ {CATEGORIES.map((category) => ( + + ))} +
+ +
+ {filteredIngredients.map((ingredient) => { + const isSelected = selectedIngredients.find((item) => item.id === ingredient.id); + return ( + + ); + })} +
+ +
+
+ 선택된 식재료: {selectedIngredients.length}개 +
+
+ + 취소 + + +
+
+
+
+ ); +}; diff --git a/src/screens/AddIngredientPage/index.js b/src/screens/AddIngredientPage/index.js new file mode 100644 index 0000000..13def78 --- /dev/null +++ b/src/screens/AddIngredientPage/index.js @@ -0,0 +1 @@ +export { AddIngredientPage } from "./AddIngredientPage"; diff --git a/src/screens/AddIngredientPage/style.css b/src/screens/AddIngredientPage/style.css new file mode 100644 index 0000000..baad900 --- /dev/null +++ b/src/screens/AddIngredientPage/style.css @@ -0,0 +1,284 @@ +.add-ingredient-page { + align-items: center; + background-color: #ffffff; + display: flex; + flex-direction: column; + min-height: 100vh; + position: relative; + width: 100%; +} + +.add-ingredient-page .add-ingredient-header { + align-self: stretch !important; + width: 100% !important; + max-width: 1280px !important; + margin: 0 auto !important; +} + +.add-ingredient-content { + align-items: flex-start; + display: flex; + flex: 1; + flex-direction: column; + gap: 20px; + padding: 20px 64px; + position: relative; + width: 100%; + max-width: 1280px; + margin: 0 auto; +} + +.add-ingredient-title-section { + align-items: flex-start; + align-self: stretch; + border-bottom: 1px solid #000000; + display: flex; + flex-direction: column; + gap: 10px; + padding-bottom: 20px; + width: 100%; +} + +.add-ingredient-title { + color: #000000; + font-family: "Inter", Helvetica; + font-size: 48px; + font-weight: 700; + letter-spacing: -0.96px; + line-height: 57.6px; + margin: 0; +} + +.add-ingredient-subtitle { + color: #0000008c; + font-family: "Inter", Helvetica; + font-size: 20px; + font-weight: 500; + letter-spacing: -0.10px; + line-height: 29.0px; + margin: 0; +} + +.add-ingredient-search-section { + align-self: stretch; + display: flex; + gap: 10px; + width: 100%; +} + +.add-ingredient-search-input { + flex: 1; + padding: 12px 20px; + border: 1px solid #e0e0e0; + border-radius: 12px; + font-family: "Inter", Helvetica; + font-size: 16px; + transition: border-color 0.2s; +} + +.add-ingredient-search-input:focus { + outline: none; + border-color: #f6910b; +} + +.add-ingredient-category-section { + align-self: stretch; + display: flex; + gap: 10px; + flex-wrap: wrap; +} + +.add-ingredient-category-btn { + padding: 8px 20px; + background-color: #e0e0e0; + border: none; + border-radius: 12px; + color: #666666; + cursor: pointer; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 600; + transition: all 0.2s; +} + +.add-ingredient-category-btn:hover { + background-color: #d0d0d0; +} + +.add-ingredient-category-btn.active { + background-color: #f6910b; + color: #ffffff; +} + +.add-ingredient-grid { + align-self: stretch; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + gap: 20px; + padding: 20px 0; + width: 100%; +} + +.add-ingredient-card { + align-items: center; + background-color: #ffffff; + border: 2px solid #e0e0e0; + border-radius: 16px; + cursor: pointer; + display: flex; + flex-direction: column; + gap: 10px; + padding: 15px; + position: relative; + transition: all 0.2s; +} + +.add-ingredient-card:hover { + border-color: #f6910b; + transform: translateY(-2px); + box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1); +} + +.add-ingredient-card.selected { + border-color: #f6910b; + background-color: #f6910b1a; +} + +.add-ingredient-card-image { + width: 80px; + height: 80px; + object-fit: cover; + border-radius: 8px; +} + +.add-ingredient-card-name { + color: #000000; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 600; + text-align: center; +} + +.add-ingredient-card-category { + color: #666666; + font-family: "Inter", Helvetica; + font-size: 12px; + font-weight: 500; + text-align: center; +} + +.add-ingredient-card-check { + position: absolute; + top: 10px; + right: 10px; + width: 24px; + height: 24px; + background-color: #f6910b; + border-radius: 50%; + color: #ffffff; + display: flex; + align-items: center; + justify-content: center; + font-size: 16px; + font-weight: 700; +} + +.add-ingredient-footer { + align-items: center; + align-self: stretch; + border-top: 1px solid #e0e0e0; + display: flex; + justify-content: space-between; + padding: 20px 0; + width: 100%; +} + +.add-ingredient-selected-count { + color: #000000; + font-family: "Inter", Helvetica; + font-size: 18px; + font-weight: 600; +} + +.add-ingredient-footer-buttons { + display: flex; + gap: 15px; +} + +.add-ingredient-cancel-btn { + padding: 12px 30px; + background-color: #e0e0e0; + border: none; + border-radius: 12px; + color: #666666; + cursor: pointer; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 600; + text-decoration: none; + transition: background-color 0.2s; + display: flex; + align-items: center; + justify-content: center; +} + +.add-ingredient-cancel-btn:hover { + background-color: #d0d0d0; +} + +.add-ingredient-submit-btn { + padding: 12px 30px; + background-color: #f6910b; + border: none; + border-radius: 12px; + color: #ffffff; + cursor: pointer; + font-family: "Inter", Helvetica; + font-size: 16px; + font-weight: 700; + transition: background-color 0.2s; +} + +.add-ingredient-submit-btn:hover:not(:disabled) { + background-color: #e58209; +} + +.add-ingredient-submit-btn:disabled { + background-color: #cccccc; + cursor: not-allowed; +} + +@media (max-width: 768px) { + .add-ingredient-content { + padding: 20px 20px; + } + + .add-ingredient-title { + font-size: 32px; + line-height: 38.4px; + } + + .add-ingredient-subtitle { + font-size: 16px; + line-height: 23.2px; + } + + .add-ingredient-grid { + grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); + gap: 15px; + } + + .add-ingredient-footer { + flex-direction: column; + gap: 15px; + } + + .add-ingredient-footer-buttons { + width: 100%; + } + + .add-ingredient-cancel-btn, + .add-ingredient-submit-btn { + flex: 1; + } +} diff --git a/src/screens/CommunityContent/CommunityContent.jsx b/src/screens/CommunityContent/CommunityContent.jsx new file mode 100644 index 0000000..d3c060f --- /dev/null +++ b/src/screens/CommunityContent/CommunityContent.jsx @@ -0,0 +1,13 @@ +import React from "react"; +import { UnifiedHeader } from "../../components/UnifiedHeader"; +import { Communitycontentpage } from "./sections/Communitycontentpage"; +import "./style.css"; + +export const CommunityContent = () => { + return ( +
+ + +
+ ); +}; diff --git a/src/screens/CommunityContent/index.js b/src/screens/CommunityContent/index.js new file mode 100644 index 0000000..9ea88ad --- /dev/null +++ b/src/screens/CommunityContent/index.js @@ -0,0 +1 @@ +export { CommunityContent } from "./CommunityContent"; diff --git a/src/screens/CommunityContent/sections/Communitycontentpage/Communitycontentpage.jsx b/src/screens/CommunityContent/sections/Communitycontentpage/Communitycontentpage.jsx new file mode 100644 index 0000000..c36c180 --- /dev/null +++ b/src/screens/CommunityContent/sections/Communitycontentpage/Communitycontentpage.jsx @@ -0,0 +1,178 @@ +import React, { useState } from "react"; +import { Link, useLocation, useParams } from "react-router-dom"; +import { useAuth } from "../../../../contexts/AuthContext"; +import { CommunitypageWrapper } from "../../../../components/CommunitypageWrapper"; +import { PageButton } from "../../../../components/PageButton"; +import "./style.css"; + +const ALL_POSTS = [ + // TODO: Backend Integration: Replace with API call to fetch all community posts + { id: 1, title: "돼지고기 100g 나눔합니다.", author: "test3User", date: "2025-11-03", category: "나눔", content: "돼지고기를 너무 많이 샀네요 남는 돼지고기 나눔해요" }, + { id: 2, title: "양파 2개 나눔해요", author: "user123", date: "2025-11-02", category: "나눔", content: "양파 2개 필요하신 분 가져가세요" }, + { id: 3, title: "닭고기 500g 나눔", author: "foodlover", date: "2025-11-01", category: "나눔", content: "신선한 닭고기 나눔합니다" }, + { id: 4, title: "고추장 새것 나눔합니다", author: "chef99", date: "2025-10-31", category: "나눔", content: "개봉 안한 고추장 드립니다" }, + { id: 5, title: "양배추 한통 가져가세요", author: "veggie_fan", date: "2025-10-30", category: "나눔", content: "양배추 한통 나눔해요" }, + { id: 6, title: "감자 5개 나눔", author: "potato_lover", date: "2025-10-29", category: "나눔", content: "감자 5개 드립니다" }, + { id: 7, title: "당근 한봉지 드립니다", author: "healthy_eater", date: "2025-10-28", category: "나눔", content: "당근 한봉지 나눔합니다" }, + { id: 8, title: "우유 1L 나눔해요", author: "milk_fan", date: "2025-10-27", category: "나눔", content: "우유 1L 필요하신 분" }, + { id: 9, title: "계란 10개 나눔", author: "egg_master", date: "2025-10-26", category: "나눔", content: "계란 10개 드립니다" }, + { id: 10, title: "토마토 나눔합니다", author: "tomato_grower", date: "2025-10-25", category: "나눔", content: "토마토 나눔해요" }, +]; + +export const Communitycontentpage = () => { + const location = useLocation(); + const { id } = useParams(); + const { user, isAuthenticated } = useAuth(); + const [newComment, setNewComment] = useState(""); + + // Load comments from localStorage for this specific post + const [comments, setComments] = useState(() => { + const storedComments = localStorage.getItem(`comments_${id}`); + return storedComments ? JSON.parse(storedComments) : []; + }); + + const post = location.state?.post || { + // TODO: Backend Integration: Fetch post details by ID if not available in state + id: id, + title: "돼지고기 100g 나눔합니다.", + author: "test3User", + date: "2025-11-03", + category: "나눔", + content: "돼지고기를 너무 많이 샀네요 남는 돼지고기 나눔해요" + }; + + // Get related posts (2 before and 2 after current post) + const currentIndex = ALL_POSTS.findIndex(p => p.id === parseInt(id)); + const relatedPosts = []; + + // Get 2 posts before + for (let i = Math.max(0, currentIndex - 2); i < currentIndex; i++) { + if (ALL_POSTS[i]) relatedPosts.push(ALL_POSTS[i]); + } + + // Get 2 posts after + for (let i = currentIndex + 1; i <= Math.min(ALL_POSTS.length - 1, currentIndex + 2); i++) { + if (ALL_POSTS[i]) relatedPosts.push(ALL_POSTS[i]); + } + + const handleCommentSubmit = (e) => { + e.preventDefault(); + if (!isAuthenticated) { + alert("로그인이 필요합니다."); + return; + } + if (!newComment.trim()) return; + + const comment = { + id: Date.now(), + author: user.username, + content: newComment, + date: new Date().toLocaleString('ko-KR') + }; + + const updatedComments = [...comments, comment]; + setComments(updatedComments); + + // TODO: Backend Integration: Replace with API call to add a new comment + // Example: axios.post(`/api/posts/${id}/comments`, comment) + + // Save comments to localStorage for this specific post (mock DB) + localStorage.setItem(`comments_${id}`, JSON.stringify(updatedComments)); + setNewComment(""); + }; + + + return ( +
+ +
재료 나눔 게시판
+ + +
+
+ Category icon + +
{post.category}
+
+ +
+
{post.title}
+
+ +
+
작성자
+ +
{post.author}
+ +
작성일
+ +
{post.date}
+
+ +
+

+ {post.content} +

+
+ +
+
+

댓글 ({comments.length})

+
+ +
+ {comments.map((comment) => ( +
+
{comment.author}
+
{comment.content}
+
{comment.date}
+
+ ))} +
+ +
+