diff --git a/nextjs/package.json b/nextjs/package.json index 7a3ae20..a57f2b5 100644 --- a/nextjs/package.json +++ b/nextjs/package.json @@ -13,10 +13,11 @@ "@next/env": "^15.0.3", "@tanstack/react-query": "^5.59.20", "@trpc/client": "11.0.0-rc.608", + "@trpc/next": "11.0.0-rc.608", "@trpc/react-query": "11.0.0-rc.608", "@trpc/server": "11.0.0-rc.608", "jsdom": "^25.0.0", - "next": "^14.2.7", + "next": "^15.0.2", "react": "^18", "react-dom": "^18", "superjson": "^2.2.1", diff --git a/nextjs/pnpm-lock.yaml b/nextjs/pnpm-lock.yaml index 2bf2fed..db32792 100644 --- a/nextjs/pnpm-lock.yaml +++ b/nextjs/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: '@trpc/client': specifier: 11.0.0-rc.608 version: 11.0.0-rc.608(@trpc/server@11.0.0-rc.608) + '@trpc/next': + specifier: 11.0.0-rc.608 + version: 11.0.0-rc.608(@tanstack/react-query@5.59.20(react@18.3.1))(@trpc/client@11.0.0-rc.608(@trpc/server@11.0.0-rc.608))(@trpc/react-query@11.0.0-rc.608(@tanstack/react-query@5.59.20(react@18.3.1))(@trpc/client@11.0.0-rc.608(@trpc/server@11.0.0-rc.608))(@trpc/server@11.0.0-rc.608)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@trpc/server@11.0.0-rc.608)(next@15.0.2(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@trpc/react-query': specifier: 11.0.0-rc.608 version: 11.0.0-rc.608(@tanstack/react-query@5.59.20(react@18.3.1))(@trpc/client@11.0.0-rc.608(@trpc/server@11.0.0-rc.608))(@trpc/server@11.0.0-rc.608)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -27,8 +30,8 @@ importers: specifier: ^25.0.0 version: 25.0.1 next: - specifier: ^14.2.7 - version: 14.2.17(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^15.0.2 + version: 15.0.2(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18 version: 18.3.1 @@ -196,6 +199,9 @@ packages: resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} + '@emnapi/runtime@1.3.1': + resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -365,6 +371,111 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -399,8 +510,8 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - '@next/env@14.2.17': - resolution: {integrity: sha512-MCgO7VHxXo8sYR/0z+sk9fGyJJU636JyRmkjc7ZJY8Hurl8df35qG5hoAh5KMs75FLjhlEo9bb2LGe89Y/scDA==} + '@next/env@15.0.2': + resolution: {integrity: sha512-c0Zr0ModK5OX7D4ZV8Jt/wqoXtitLNPwUfG9zElCZztdaZyNVnN40rDXVZ/+FGuR4CcNV5AEfM6N8f+Ener7Dg==} '@next/env@15.0.3': resolution: {integrity: sha512-t9Xy32pjNOvVn2AS+Utt6VmyrshbpfUMhIjFO60gI58deSo/KgLOp31XZ4O+kY/Is8WAGYwA5gR7kOb1eORDBA==} @@ -408,56 +519,50 @@ packages: '@next/eslint-plugin-next@14.2.17': resolution: {integrity: sha512-fW6/u1jjlBQrMs1ExyINehaK3B+LEW5UqdF6QYL07QK+SECkX0hnEyPMaNKj0ZFzirQ9D8jLWQ00P8oua4yx9g==} - '@next/swc-darwin-arm64@14.2.17': - resolution: {integrity: sha512-WiOf5nElPknrhRMTipXYTJcUz7+8IAjOYw3vXzj3BYRcVY0hRHKWgTgQ5439EvzQyHEko77XK+yN9x9OJ0oOog==} + '@next/swc-darwin-arm64@15.0.2': + resolution: {integrity: sha512-GK+8w88z+AFlmt+ondytZo2xpwlfAR8U6CRwXancHImh6EdGfHMIrTSCcx5sOSBei00GyLVL0ioo1JLKTfprgg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@14.2.17': - resolution: {integrity: sha512-29y425wYnL17cvtxrDQWC3CkXe/oRrdt8ie61S03VrpwpPRI0XsnTvtKO06XCisK4alaMnZlf8riwZIbJTaSHQ==} + '@next/swc-darwin-x64@15.0.2': + resolution: {integrity: sha512-KUpBVxIbjzFiUZhiLIpJiBoelqzQtVZbdNNsehhUn36e2YzKHphnK8eTUW1s/4aPy5kH/UTid8IuVbaOpedhpw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@14.2.17': - resolution: {integrity: sha512-SSHLZls3ZwNEHsc+d0ynKS+7Af0Nr8+KTUBAy9pm6xz9SHkJ/TeuEg6W3cbbcMSh6j4ITvrjv3Oi8n27VR+IPw==} + '@next/swc-linux-arm64-gnu@15.0.2': + resolution: {integrity: sha512-9J7TPEcHNAZvwxXRzOtiUvwtTD+fmuY0l7RErf8Yyc7kMpE47MIQakl+3jecmkhOoIyi/Rp+ddq7j4wG6JDskQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@14.2.17': - resolution: {integrity: sha512-VFge37us5LNPatB4F7iYeuGs9Dprqe4ZkW7lOEJM91r+Wf8EIdViWHLpIwfdDXinvCdLl6b4VyLpEBwpkctJHA==} + '@next/swc-linux-arm64-musl@15.0.2': + resolution: {integrity: sha512-BjH4ZSzJIoTTZRh6rG+a/Ry4SW0HlizcPorqNBixBWc3wtQtj4Sn9FnRZe22QqrPnzoaW0ctvSz4FaH4eGKMww==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@14.2.17': - resolution: {integrity: sha512-aaQlpxUVb9RZ41adlTYVQ3xvYEfBPUC8+6rDgmQ/0l7SvK8S1YNJzPmDPX6a4t0jLtIoNk7j+nroS/pB4nx7vQ==} + '@next/swc-linux-x64-gnu@15.0.2': + resolution: {integrity: sha512-i3U2TcHgo26sIhcwX/Rshz6avM6nizrZPvrDVDY1bXcLH1ndjbO8zuC7RoHp0NSK7wjJMPYzm7NYL1ksSKFreA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@14.2.17': - resolution: {integrity: sha512-HSyEiFaEY3ay5iATDqEup5WAfrhMATNJm8dYx3ZxL+e9eKv10XKZCwtZByDoLST7CyBmyDz+OFJL1wigyXeaoA==} + '@next/swc-linux-x64-musl@15.0.2': + resolution: {integrity: sha512-AMfZfSVOIR8fa+TXlAooByEF4OB00wqnms1sJ1v+iu8ivwvtPvnkwdzzFMpsK5jA2S9oNeeQ04egIWVb4QWmtQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@14.2.17': - resolution: {integrity: sha512-h5qM9Btqv87eYH8ArrnLoAHLyi79oPTP2vlGNSg4CDvUiXgi7l0+5KuEGp5pJoMhjuv9ChRdm7mRlUUACeBt4w==} + '@next/swc-win32-arm64-msvc@15.0.2': + resolution: {integrity: sha512-JkXysDT0/hEY47O+Hvs8PbZAeiCQVxKfGtr4GUpNAhlG2E0Mkjibuo8ryGD29Qb5a3IOnKYNoZlh/MyKd2Nbww==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-ia32-msvc@14.2.17': - resolution: {integrity: sha512-BD/G++GKSLexQjdyoEUgyo5nClU7er5rK0sE+HlEqnldJSm96CIr/+YOTT063LVTT/dUOeQsNgp5DXr86/K7/A==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - - '@next/swc-win32-x64-msvc@14.2.17': - resolution: {integrity: sha512-vkQfN1+4V4KqDibkW2q0sJ6CxQuXq5l2ma3z0BRcfIqkAMZiiW67T9yCpwqJKP68QghBtPEFjPAlaqe38O6frw==} + '@next/swc-win32-x64-msvc@15.0.2': + resolution: {integrity: sha512-foaUL0NqJY/dX0Pi/UcZm5zsmSk5MtP/gxx3xOPyREkMFN+CTjctPfu3QaqrQHinaKdPnMWPJDKt4VjDfTBe/Q==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -581,8 +686,8 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.5.5': - resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} + '@swc/helpers@0.5.13': + resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} '@tanstack/query-core@5.59.20': resolution: {integrity: sha512-e8vw0lf7KwfGe1if4uPFhvZRWULqHjFcz3K8AebtieXvnMOz5FSzlZe3mTLlPuUBcydCnBRqYs2YJ5ys68wwLg==} @@ -616,6 +721,22 @@ packages: peerDependencies: '@trpc/server': 11.0.0-rc.608+f75de97b3 + '@trpc/next@11.0.0-rc.608': + resolution: {integrity: sha512-dL+ifSaJIl+21P3LZ1JEl1uzqDD7pZ3iCs9uEnf3tjyZhbCuavnTL7faRDV6wZ6+L6opzKxIzeVNC4e490Ys0Q==} + peerDependencies: + '@tanstack/react-query': ^5.59.15 + '@trpc/client': 11.0.0-rc.608+f75de97b3 + '@trpc/react-query': 11.0.0-rc.608+f75de97b3 + '@trpc/server': 11.0.0-rc.608+f75de97b3 + next: 15.0.2 + react: '>=16.8.0' + react-dom: '>=16.8.0' + peerDependenciesMeta: + '@tanstack/react-query': + optional: true + '@trpc/react-query': + optional: true + '@trpc/react-query@11.0.0-rc.608': resolution: {integrity: sha512-V0UJltzCfdn3PqePqbB8TK64aNXVBpdoLEC4OdMtTYiZTsAnH1jTwrNOBji3Xwm8Q0n4jaUDrIz5M/5IPjYrGg==} peerDependencies: @@ -947,6 +1068,13 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -1043,6 +1171,10 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -1446,6 +1578,9 @@ packages: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-async-function@2.0.0: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} @@ -1733,21 +1868,24 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - next@14.2.17: - resolution: {integrity: sha512-hNo/Zy701DDO3nzKkPmsLRlDfNCtb1OJxFUvjGEl04u7SFa3zwC6hqsOUzMajcaEOEV8ey1GjvByvrg0Qr5AiQ==} - engines: {node: '>=18.17.0'} + next@15.0.2: + resolution: {integrity: sha512-rxIWHcAu4gGSDmwsELXacqAPUk+j8dV/A9cDF5fsiCMpkBDYkO2AEaL1dfD+nNmDiU6QMCFN8Q30VEKapT9UHQ==} + engines: {node: '>=18.18.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 '@playwright/test': ^1.41.2 - react: ^18.2.0 - react-dom: ^18.2.0 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-02c0e824-20241028 + react-dom: ^18.2.0 || 19.0.0-rc-02c0e824-20241028 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': optional: true '@playwright/test': optional: true + babel-plugin-react-compiler: + optional: true sass: optional: true @@ -2052,6 +2190,10 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2071,6 +2213,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2134,13 +2279,13 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - styled-jsx@5.1.1: - resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} engines: {node: '>= 12.0.0'} peerDependencies: '@babel/core': '*' babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' peerDependenciesMeta: '@babel/core': optional: true @@ -2563,6 +2708,11 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@emnapi/runtime@1.3.1': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -2667,6 +2817,81 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.3.1 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -2705,7 +2930,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@next/env@14.2.17': {} + '@next/env@15.0.2': {} '@next/env@15.0.3': {} @@ -2713,31 +2938,28 @@ snapshots: dependencies: glob: 10.3.10 - '@next/swc-darwin-arm64@14.2.17': + '@next/swc-darwin-arm64@15.0.2': optional: true - '@next/swc-darwin-x64@14.2.17': + '@next/swc-darwin-x64@15.0.2': optional: true - '@next/swc-linux-arm64-gnu@14.2.17': + '@next/swc-linux-arm64-gnu@15.0.2': optional: true - '@next/swc-linux-arm64-musl@14.2.17': + '@next/swc-linux-arm64-musl@15.0.2': optional: true - '@next/swc-linux-x64-gnu@14.2.17': + '@next/swc-linux-x64-gnu@15.0.2': optional: true - '@next/swc-linux-x64-musl@14.2.17': + '@next/swc-linux-x64-musl@15.0.2': optional: true - '@next/swc-win32-arm64-msvc@14.2.17': + '@next/swc-win32-arm64-msvc@15.0.2': optional: true - '@next/swc-win32-ia32-msvc@14.2.17': - optional: true - - '@next/swc-win32-x64-msvc@14.2.17': + '@next/swc-win32-x64-msvc@15.0.2': optional: true '@nodelib/fs.scandir@2.1.5': @@ -2817,9 +3039,8 @@ snapshots: '@swc/counter@0.1.3': {} - '@swc/helpers@0.5.5': + '@swc/helpers@0.5.13': dependencies: - '@swc/counter': 0.1.3 tslib: 2.8.1 '@tanstack/query-core@5.59.20': {} @@ -2854,6 +3075,17 @@ snapshots: dependencies: '@trpc/server': 11.0.0-rc.608 + '@trpc/next@11.0.0-rc.608(@tanstack/react-query@5.59.20(react@18.3.1))(@trpc/client@11.0.0-rc.608(@trpc/server@11.0.0-rc.608))(@trpc/react-query@11.0.0-rc.608(@tanstack/react-query@5.59.20(react@18.3.1))(@trpc/client@11.0.0-rc.608(@trpc/server@11.0.0-rc.608))(@trpc/server@11.0.0-rc.608)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@trpc/server@11.0.0-rc.608)(next@15.0.2(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@trpc/client': 11.0.0-rc.608(@trpc/server@11.0.0-rc.608) + '@trpc/server': 11.0.0-rc.608 + next: 15.0.2(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@tanstack/react-query': 5.59.20(react@18.3.1) + '@trpc/react-query': 11.0.0-rc.608(@tanstack/react-query@5.59.20(react@18.3.1))(@trpc/client@11.0.0-rc.608(@trpc/server@11.0.0-rc.608))(@trpc/server@11.0.0-rc.608)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@trpc/react-query@11.0.0-rc.608(@tanstack/react-query@5.59.20(react@18.3.1))(@trpc/client@11.0.0-rc.608(@trpc/server@11.0.0-rc.608))(@trpc/server@11.0.0-rc.608)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@tanstack/react-query': 5.59.20(react@18.3.1) @@ -3260,6 +3492,18 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + optional: true + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -3343,6 +3587,9 @@ snapshots: dequal@2.0.3: {} + detect-libc@2.0.3: + optional: true + didyoumean@1.2.2: {} dlv@1.1.3: {} @@ -3921,6 +4168,9 @@ snapshots: call-bind: 1.0.7 get-intrinsic: 1.2.4 + is-arrayish@0.3.2: + optional: true + is-async-function@2.0.0: dependencies: has-tostringtag: 1.0.2 @@ -4200,27 +4450,27 @@ snapshots: natural-compare@1.4.0: {} - next@14.2.17(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@15.0.2(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 14.2.17 - '@swc/helpers': 0.5.5 + '@next/env': 15.0.2 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.13 busboy: 1.6.0 caniuse-lite: 1.0.30001678 - graceful-fs: 4.2.11 postcss: 8.4.31 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.1(@babel/core@7.26.0)(react@18.3.1) + styled-jsx: 5.1.6(@babel/core@7.26.0)(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.17 - '@next/swc-darwin-x64': 14.2.17 - '@next/swc-linux-arm64-gnu': 14.2.17 - '@next/swc-linux-arm64-musl': 14.2.17 - '@next/swc-linux-x64-gnu': 14.2.17 - '@next/swc-linux-x64-musl': 14.2.17 - '@next/swc-win32-arm64-msvc': 14.2.17 - '@next/swc-win32-ia32-msvc': 14.2.17 - '@next/swc-win32-x64-msvc': 14.2.17 + '@next/swc-darwin-arm64': 15.0.2 + '@next/swc-darwin-x64': 15.0.2 + '@next/swc-linux-arm64-gnu': 15.0.2 + '@next/swc-linux-arm64-musl': 15.0.2 + '@next/swc-linux-x64-gnu': 15.0.2 + '@next/swc-linux-x64-musl': 15.0.2 + '@next/swc-win32-arm64-msvc': 15.0.2 + '@next/swc-win32-x64-msvc': 15.0.2 + sharp: 0.33.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -4543,6 +4793,33 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.6.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -4560,6 +4837,11 @@ snapshots: signal-exit@4.1.0: {} + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + optional: true + source-map-js@1.2.1: {} stackback@0.0.2: {} @@ -4639,7 +4921,7 @@ snapshots: strip-json-comments@3.1.1: {} - styled-jsx@5.1.1(@babel/core@7.26.0)(react@18.3.1): + styled-jsx@5.1.6(@babel/core@7.26.0)(react@18.3.1): dependencies: client-only: 0.0.1 react: 18.3.1 diff --git a/nextjs/src/app/course/[courseName]/calendar/day/DayTitle.tsx b/nextjs/src/app/course/[courseName]/calendar/day/DayTitle.tsx index 09b60d7..3753a28 100644 --- a/nextjs/src/app/course/[courseName]/calendar/day/DayTitle.tsx +++ b/nextjs/src/app/course/[courseName]/calendar/day/DayTitle.tsx @@ -1,5 +1,4 @@ import Modal, { useModal } from "@/components/Modal"; -import { useLecturesByWeekQuery } from "@/hooks/localCourse/lectureHooks"; import { getLectureUrl } from "@/services/urlUtils"; import Link from "next/link"; import { useCourseContext } from "../../context/courseContext"; @@ -7,10 +6,11 @@ import NewItemForm from "../../modules/NewItemForm"; import { DraggableItem } from "../../context/drag/draggingContext"; import { useDragStyleContext } from "../../context/drag/dragStyleContext"; import { getLectureForDay } from "@/models/local/lectureUtils"; +import { trpc } from "@/services/trpc/utils"; export function DayTitle({ day, dayAsDate }: { day: string; dayAsDate: Date }) { const { courseName } = useCourseContext(); - const { data: weeks } = useLecturesByWeekQuery(); + const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName }); const { setIsDragging } = useDragStyleContext(); const todaysLecture = getLectureForDay(weeks, dayAsDate); const modal = useModal(); diff --git a/nextjs/src/app/course/[courseName]/context/drag/useItemDropOnDay.ts b/nextjs/src/app/course/[courseName]/context/drag/useItemDropOnDay.ts index 9b605e6..f7f1ba3 100644 --- a/nextjs/src/app/course/[courseName]/context/drag/useItemDropOnDay.ts +++ b/nextjs/src/app/course/[courseName]/context/drag/useItemDropOnDay.ts @@ -1,9 +1,6 @@ "use client"; import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks"; -import { - useLecturesByWeekQuery, - useLectureUpdateMutation, -} from "@/hooks/localCourse/lectureHooks"; +import { useLectureUpdateMutation } from "@/hooks/localCourse/lectureHooks"; import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks"; import { LocalAssignment } from "@/models/local/assignment/localAssignment"; @@ -20,6 +17,7 @@ import { Dispatch, SetStateAction, useCallback, DragEvent } from "react"; import { DraggableItem } from "./draggingContext"; import { getNewLockDate } from "./getNewLockDate"; import { useUpdateItemMutation } from "@/hooks/localCourse/courseItemHooks"; +import { trpc } from "@/services/trpc/utils"; export function useItemDropOnDay({ setIsDragging, @@ -35,7 +33,10 @@ export function useItemDropOnDay({ modal: { isOpen: boolean; openModal: () => void; closeModal: () => void }; }) { const { data: settings } = useLocalCourseSettingsQuery(); - const { data: weeks } = useLecturesByWeekQuery(); + // const { data: weeks } = useLecturesByWeekQuery(); + const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ + courseName: settings.name, + }); const updateQuizMutation = useUpdateItemMutation("Quiz"); const updateLectureMutation = useLectureUpdateMutation(); const updateAssignmentMutation = useUpdateAssignmentMutation(); diff --git a/nextjs/src/app/course/[courseName]/layout.tsx b/nextjs/src/app/course/[courseName]/layout.tsx index 8685634..58279a4 100644 --- a/nextjs/src/app/course/[courseName]/layout.tsx +++ b/nextjs/src/app/course/[courseName]/layout.tsx @@ -1,5 +1,4 @@ import { fileStorageService } from "@/services/fileStorage/fileStorageService"; -import CourseContextProvider from "./context/CourseContextProvider"; import { Suspense } from "react"; import { getQueryClient } from "@/app/providersQueryClientUtils"; import { dehydrate, HydrationBoundary } from "@tanstack/react-query"; @@ -8,69 +7,35 @@ import { createServerSideHelpers } from "@trpc/react-query/server"; import { trpcAppRouter } from "@/services/trpc/router/app"; import { createTrpcContext } from "@/services/trpc/context"; import superjson from "superjson"; +import CourseContextProvider from "./context/CourseContextProvider"; export default async function CourseLayout({ children, - params: { courseName }, + params, }: { children: React.ReactNode; - params: { courseName: string }; + params: Promise<{ courseName: string }>; }) { + const { courseName } = await params; const decodedCourseName = decodeURIComponent(courseName); if (courseName.includes(".js.map")) { console.log("cannot load course that is .js.map " + decodedCourseName); return
; } - const settings = await fileStorageService.settings.getCourseSettings( - decodedCourseName - ); - const queryClient = getQueryClient(); - await hydrateCanvasCourse(settings.canvasId, queryClient); - const dehydratedState = dehydrate(queryClient); - const trpcHelper = createServerSideHelpers({ - router: trpcAppRouter, - ctx: createTrpcContext(), - transformer: superjson, - }); + // const settings = await fileStorageService.settings.getCourseSettings( + // decodedCourseName + // ); + // const queryClient = getQueryClient(); + // await hydrateCanvasCourse(settings.canvasId, queryClient); + // const dehydratedState = dehydrate(queryClient); - const allSettings = await fileStorageService.settings.getAllCoursesSettings(); - await Promise.all( - allSettings.map(async (settings) => { - const courseName = settings.name; - const moduleNames = await fileStorageService.modules.getModuleNames( - courseName - ); - await Promise.all( - moduleNames.map(async (moduleName) => { - await trpcHelper.assignment.getAllAssignments.prefetch({ - courseName, - moduleName, - }); - - // await Promise.all( - // assignments.map( - // async (a) => - // await trpcHelper.assignment.getAssignment.fetch({ - // courseName, - // moduleName, - // assignmentName: a.name, - // }) - // ) - // ); - }) - ); - }) - ); - const dehydratedTrpc = trpcHelper.dehydrate(); return ( - - - - {children} - - - + {/* */} + + {children} + + {/* */} ); } diff --git a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx index 874ff11..fba74a7 100644 --- a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx +++ b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx @@ -2,7 +2,6 @@ import { MonacoEditor } from "@/components/editor/MonacoEditor"; import { - useLecturesByWeekQuery, useLectureUpdateMutation, } from "@/hooks/localCourse/lectureHooks"; import { @@ -13,9 +12,13 @@ import { useEffect, useState } from "react"; import LecturePreview from "./LecturePreview"; import EditLectureTitle from "./EditLectureTitle"; import LectureButtons from "./LectureButtons"; +import { trpc } from "@/services/trpc/utils"; +import { useCourseContext } from "../../context/courseContext"; export default function EditLecture({ lectureDay }: { lectureDay: string }) { - const { data: weeks } = useLecturesByWeekQuery(); + // const { data: weeks } = useLecturesByWeekQuery(); + const { courseName } = useCourseContext(); + const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName }); const updateLecture = useLectureUpdateMutation(); const lecture = weeks diff --git a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/preview/LecturePreviewPage.tsx b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/preview/LecturePreviewPage.tsx index 517adcd..f8915b3 100644 --- a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/preview/LecturePreviewPage.tsx +++ b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/preview/LecturePreviewPage.tsx @@ -1,10 +1,10 @@ "use client"; -import { useLecturesByWeekQuery } from "@/hooks/localCourse/lectureHooks"; import LecturePreview from "../LecturePreview"; import { getCourseUrl, getLectureUrl } from "@/services/urlUtils"; import { useCourseContext } from "../../../context/courseContext"; import Link from "next/link"; +import { trpc } from "@/services/trpc/utils"; export default function LecturePreviewPage({ lectureDay, @@ -12,7 +12,7 @@ export default function LecturePreviewPage({ lectureDay: string; }) { const { courseName } = useCourseContext(); - const { data: weeks } = useLecturesByWeekQuery(); + const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName }); const lecture = weeks .flatMap(({ lectures }) => lectures.map((lecture) => lecture)) .find((l) => l.date === lectureDay); diff --git a/nextjs/src/app/course/[courseName]/modules/ExpandableModule.tsx b/nextjs/src/app/course/[courseName]/modules/ExpandableModule.tsx index 6e7e612..f466714 100644 --- a/nextjs/src/app/course/[courseName]/modules/ExpandableModule.tsx +++ b/nextjs/src/app/course/[courseName]/modules/ExpandableModule.tsx @@ -31,15 +31,15 @@ export default function ExpandableModule({ }) { const { itemDropOnModule } = useDraggingContext(); - const [assignments] = useAssignmentsQuery(moduleName); - const { data: quizzes } = useItemsQueries(moduleName, "Quiz"); + const { data: assignments } = useAssignmentsQuery(moduleName); + // const { data: quizzes } = useItemsQueries(moduleName, "Quiz"); const { data: pages } = usePagesQueries(moduleName); const modal = useModal(); const moduleItems: { type: "assignment" | "quiz" | "page"; item: IModuleItem; - }[] = assignments + }[] = (assignments ?? []) .map( ( a @@ -51,7 +51,7 @@ export default function ExpandableModule({ item: a, }) ) - .concat(quizzes.map((q) => ({ type: "quiz", item: q }))) + // .concat(quizzes.map((q) => ({ type: "quiz", item: q }))) .concat(pages.map((p) => ({ type: "page", item: p }))) .sort( (a, b) => diff --git a/nextjs/src/app/layout.tsx b/nextjs/src/app/layout.tsx index 09827db..4194144 100644 --- a/nextjs/src/app/layout.tsx +++ b/nextjs/src/app/layout.tsx @@ -4,7 +4,7 @@ import Providers from "./providers"; import { Suspense } from "react"; import { getQueryClient } from "./providersQueryClientUtils"; import { hydrateCourses } from "@/hooks/hookHydration"; -import { dehydrate, HydrationBoundary } from "@tanstack/react-query"; +import { dehydrate, hydrate, HydrationBoundary } from "@tanstack/react-query"; import { MyToaster } from "./MyToaster"; import { cookies } from "next/headers"; import { createServerSideHelpers } from "@trpc/react-query/server"; @@ -13,6 +13,7 @@ import { createTrpcContext } from "@/services/trpc/context"; import superjson from "superjson"; import { fileStorageService } from "@/services/fileStorage/fileStorageService"; import ClientOnly from "@/components/ClientOnly"; +import { createTRPCQueryUtils } from "@trpc/react-query"; export const dynamic = "force-dynamic"; export const metadata: Metadata = { @@ -24,47 +25,6 @@ export default async function RootLayout({ }: Readonly<{ children: React.ReactNode; }>) { - const queryClient = getQueryClient(); - await hydrateCourses(queryClient); - const dehydratedState = dehydrate(queryClient); - cookies(); // disables static page generation at build time - - const trpcHelper = createServerSideHelpers({ - router: trpcAppRouter, - ctx: createTrpcContext(), - transformer: superjson, - }); - - const allSettings = await fileStorageService.settings.getAllCoursesSettings(); - await Promise.all( - allSettings.map(async (settings) => { - const courseName = settings.name; - const moduleNames = await fileStorageService.modules.getModuleNames( - courseName - ); - await Promise.all( - moduleNames.map(async (moduleName) => { - await trpcHelper.assignment.getAllAssignments.prefetch({ - courseName, - moduleName, - }); - - // await Promise.all( - // assignments.map( - // async (a) => - // await trpcHelper.assignment.getAssignment.fetch({ - // courseName, - // moduleName, - // assignmentName: a.name, - // }) - // ) - // ); - }) - ); - }) - ); - - const dehydratedTrpc = trpcHelper.dehydrate(); return ( @@ -73,11 +33,7 @@ export default async function RootLayout({ - - - {children} - - + {children} diff --git a/nextjs/src/app/page.tsx b/nextjs/src/app/page.tsx index db686e1..6650f77 100644 --- a/nextjs/src/app/page.tsx +++ b/nextjs/src/app/page.tsx @@ -1,25 +1,70 @@ +import { hydrateCourses } from "@/hooks/hookHydration"; +import { fileStorageService } from "@/services/fileStorage/fileStorageService"; +import { createTrpcContext } from "@/services/trpc/context"; +import { trpcAppRouter } from "@/services/trpc/router/app"; +import { dehydrate, HydrationBoundary } from "@tanstack/react-query"; +import { createServerSideHelpers } from "@trpc/react-query/server"; import CourseList from "./CourseList"; import AddNewCourse from "./newCourse/AddNewCourse"; import TodaysLectures from "./todaysLectures/TodaysLectures"; +import superjson from "superjson"; +import { trpc } from "@/services/trpc/utils"; export default async function Home() { + const trpcHelper = createServerSideHelpers({ + router: trpcAppRouter, + ctx: createTrpcContext(), + transformer: superjson, + }); + const allSettings = await fileStorageService.settings.getAllCoursesSettings(); + await Promise.all( + allSettings.map(async (settings) => { + const courseName = settings.name; + const moduleNames = await fileStorageService.modules.getModuleNames( + courseName + ); + await Promise.all( + moduleNames.map( + async (moduleName) => + await trpcHelper.assignment.getAllAssignments.fetch({ + courseName, + moduleName, + }) + ) + ); + }) + ); + + await Promise.all( + allSettings.map( + async (settings) => + await trpcHelper.lectures.getLectures.prefetch({ courseName: settings.name }) + ) + ); + + await hydrateCourses(trpcHelper.queryClient); + + const dehydratedState = dehydrate(trpcHelper.queryClient); + // console.log("dehydratedState", dehydratedState); return ( -
-
-
-
-
-
-
- + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+
-
-
- -
-
- -
-
+ + ); } diff --git a/nextjs/src/app/providers.tsx b/nextjs/src/app/providers.tsx index 8bdb558..e39a1c6 100644 --- a/nextjs/src/app/providers.tsx +++ b/nextjs/src/app/providers.tsx @@ -1,11 +1,15 @@ "use client"; -import { QueryClientProvider } from "@tanstack/react-query"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ReactNode } from "react"; import { getQueryClient } from "./providersQueryClientUtils"; import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling"; import TrpcProvider from "@/services/trpc/TrpcProvider"; -export default function Providers({ children }: { children: ReactNode }) { +export default function Providers({ + children, +}: { + children: ReactNode; +}) { // NOTE: Avoid useState when initializing the query client if you don't // have a suspense boundary between this and the code that may // suspend because React will throw away the client on the initial diff --git a/nextjs/src/app/todaysLectures/OneCourseLectures.tsx b/nextjs/src/app/todaysLectures/OneCourseLectures.tsx index 63b1050..aaa9e8d 100644 --- a/nextjs/src/app/todaysLectures/OneCourseLectures.tsx +++ b/nextjs/src/app/todaysLectures/OneCourseLectures.tsx @@ -1,19 +1,21 @@ "use client"; -import { useLecturesByWeekQuery } from "@/hooks/localCourse/lectureHooks"; import { getDateOnlyMarkdownString } from "@/models/local/timeUtils"; import { getLecturePreviewUrl } from "@/services/urlUtils"; import Link from "next/link"; import { useCourseContext } from "../course/[courseName]/context/courseContext"; import { getLectureForDay } from "@/models/local/lectureUtils"; +import { trpc } from "@/services/trpc/utils"; export default function OneCourseLectures() { const { courseName } = useCourseContext(); - const { data: weeks } = useLecturesByWeekQuery(); + // const { data: weeks } = useLecturesByWeekQuery(); + const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName }); const dayAsDate = new Date(); const dayAsString = getDateOnlyMarkdownString(dayAsDate); const todaysLecture = getLectureForDay(weeks, dayAsDate); + if (!todaysLecture) return <>; return ( { @@ -61,7 +61,7 @@ export const hydrateCourse = async ( moduleNames.map((moduleName) => loadAllModuleData(courseName, moduleName)) ); - await queryClient.prefetchQuery(getLecturesQueryConfig(courseName)); + // await queryClient.prefetchQuery(getLecturesQueryConfig(courseName)); await queryClient.prefetchQuery({ queryKey: localCourseKeys.settings(courseName), diff --git a/nextjs/src/hooks/localCourse/assignmentHooks.ts b/nextjs/src/hooks/localCourse/assignmentHooks.ts index f85b6b1..be8c27c 100644 --- a/nextjs/src/hooks/localCourse/assignmentHooks.ts +++ b/nextjs/src/hooks/localCourse/assignmentHooks.ts @@ -35,6 +35,7 @@ export const useAssignmentQuery = ( export const useAssignmentsQuery = (moduleName: string) => { const { courseName } = useCourseContext(); + console.log("rendering all assignments query"); return trpc.assignment.getAllAssignments.useQuery({ moduleName, courseName, diff --git a/nextjs/src/hooks/localCourse/lectureHooks.ts b/nextjs/src/hooks/localCourse/lectureHooks.ts index 162438f..c1f991b 100644 --- a/nextjs/src/hooks/localCourse/lectureHooks.ts +++ b/nextjs/src/hooks/localCourse/lectureHooks.ts @@ -13,16 +13,16 @@ import { import { Lecture } from "@/models/local/lecture"; import { useLocalCourseSettingsQuery } from "./localCoursesHooks"; -export const getLecturesQueryConfig = (courseName: string) => - ({ - queryKey: lectureKeys.allLectures(courseName), - queryFn: async () => await getLectures(courseName), - } as const); +// export const getLecturesQueryConfig = (courseName: string) => +// ({ +// queryKey: lectureKeys.allLectures(courseName), +// queryFn: async () => await getLectures(courseName), +// } as const); -export const useLecturesByWeekQuery = () => { - const { courseName } = useCourseContext(); - return useSuspenseQuery(getLecturesQueryConfig(courseName)); -}; +// export const useLecturesByWeekQuery = () => { +// const { courseName } = useCourseContext(); +// return useSuspenseQuery(getLecturesQueryConfig(courseName)); +// }; export const useLectureUpdateMutation = () => { const { courseName } = useCourseContext(); diff --git a/nextjs/src/hooks/localCourse/localCourseModuleHooks.ts b/nextjs/src/hooks/localCourse/localCourseModuleHooks.ts index 7220f3c..63a3326 100644 --- a/nextjs/src/hooks/localCourse/localCourseModuleHooks.ts +++ b/nextjs/src/hooks/localCourse/localCourseModuleHooks.ts @@ -67,35 +67,35 @@ export const useAllCourseDataQuery = () => { // }), // }); - const { data: quizzesAndModules } = useSuspenseQueries({ - queries: moduleNames.map((moduleName) => - getAllItemsQueryConfig(courseName, moduleName, "Quiz") - ), - combine: (results) => ({ - data: results.flatMap((r, i) => - r.data.map((quiz) => ({ - moduleName: moduleNames[i], - quiz, - })) - ), - pending: results.some((r) => r.isPending), - }), - }); + // const { data: quizzesAndModules } = useSuspenseQueries({ + // queries: moduleNames.map((moduleName) => + // getAllItemsQueryConfig(courseName, moduleName, "Quiz") + // ), + // combine: (results) => ({ + // data: results.flatMap((r, i) => + // r.data.map((quiz) => ({ + // moduleName: moduleNames[i], + // quiz, + // })) + // ), + // pending: results.some((r) => r.isPending), + // }), + // }); - const { data: pagesAndModules } = useSuspenseQueries({ - queries: moduleNames.map((moduleName) => - getAllItemsQueryConfig(courseName, moduleName, "Page") - ), - combine: (results) => ({ - data: results.flatMap((r, i) => - r.data.map((page) => ({ - moduleName: moduleNames[i], - page, - })) - ), - pending: results.some((r) => r.isPending), - }), - }); + // const { data: pagesAndModules } = useSuspenseQueries({ + // queries: moduleNames.map((moduleName) => + // getAllItemsQueryConfig(courseName, moduleName, "Page") + // ), + // combine: (results) => ({ + // data: results.flatMap((r, i) => + // r.data.map((page) => ({ + // moduleName: moduleNames[i], + // page, + // })) + // ), + // pending: results.some((r) => r.isPending), + // }), + // }); - return { assignmentsAndModules, quizzesAndModules, pagesAndModules }; + return { assignmentsAndModules, quizzesAndModules: [], pagesAndModules: [] }; }; diff --git a/nextjs/src/services/trpc/TrpcProvider.tsx b/nextjs/src/services/trpc/TrpcProvider.tsx index cadc6cc..f6639ed 100644 --- a/nextjs/src/services/trpc/TrpcProvider.tsx +++ b/nextjs/src/services/trpc/TrpcProvider.tsx @@ -11,11 +11,12 @@ export default function TrpcProvider({ children: React.ReactNode; }) { // NOTE: Your production URL environment variable may be different - const url = "/api/trpc"; - // process.env.NEXT_PUBLIC_APP_DOMAIN && - // !process.env.NEXT_PUBLIC_APP_DOMAIN.includes("localhost") - // ? `https://www.${process.env.NEXT_PUBLIC_APP_DOMAIN}/api/trpc/` - // : "http://localhost:3000/api/trpc/"; + const url = "http://localhost:3000/api/trpc/" + //"/api/trpc"; + // process.env.NEXT_PUBLIC_APP_DOMAIN && + // !process.env.NEXT_PUBLIC_APP_DOMAIN.includes("localhost") + // ? `https://www.${process.env.NEXT_PUBLIC_APP_DOMAIN}/api/trpc/` + // : "http://localhost:3000/api/trpc/"; const [trpcClient] = useState(() => trpc.createClient({ diff --git a/nextjs/src/services/trpc/router/app.ts b/nextjs/src/services/trpc/router/app.ts index 67dc1aa..2bc507c 100644 --- a/nextjs/src/services/trpc/router/app.ts +++ b/nextjs/src/services/trpc/router/app.ts @@ -2,6 +2,7 @@ import { createTrpcContext } from "../context"; import publicProcedure from "../procedures/public"; import { createCallerFactory, router } from "../trpc"; import { assignmentRouter } from "./assignmentRouter"; +import { lectureRouter } from "./lectureRouter"; export const helloRouter = router({ sayHello: publicProcedure.query(() => { @@ -14,6 +15,7 @@ export const helloRouter = router({ export const trpcAppRouter = router({ hello: helloRouter, assignment: assignmentRouter, + lectures: lectureRouter, }); export const createCaller = createCallerFactory(trpcAppRouter); diff --git a/nextjs/src/services/trpc/router/lectureRouter.ts b/nextjs/src/services/trpc/router/lectureRouter.ts new file mode 100644 index 0000000..8f33bc9 --- /dev/null +++ b/nextjs/src/services/trpc/router/lectureRouter.ts @@ -0,0 +1,15 @@ +import { z } from "zod"; +import publicProcedure from "../procedures/public"; +import { router } from "../trpc"; +import { getLectures } from "@/services/fileStorage/lectureFileStorageService"; + + +export const lectureRouter = router({ + getLectures: publicProcedure + .input(z.object({ + courseName: z.string() + })) + .query(async ({input: {courseName}}) => { + return await getLectures(courseName) + }) +}) \ No newline at end of file diff --git a/nextjs/src/services/trpc/utils.ts b/nextjs/src/services/trpc/utils.ts index 90cb11d..89e8807 100644 --- a/nextjs/src/services/trpc/utils.ts +++ b/nextjs/src/services/trpc/utils.ts @@ -1,4 +1,50 @@ -import { createTRPCReact } from "@trpc/react-query"; +import { createTRPCReact, httpBatchLink } from "@trpc/react-query"; +import { createTRPCNext } from "@trpc/next"; +import { ssrPrepass } from '@trpc/next/ssrPrepass'; import { AppRouter } from "./router/app"; +import superjson from "superjson"; export const trpc = createTRPCReact(); +// export const trpc = createTRPCNext({ +// ssr: true, +// ssrPrepass, +// transformer: superjson, +// config(opts) { +// const { ctx } = opts; +// if (typeof window !== "undefined") { +// // during client requests +// return { +// links: [ +// httpBatchLink({ +// url: "/api/trpc", +// transformer: superjson, +// }), +// ], +// }; +// } +// return { +// links: [ +// httpBatchLink({ +// transformer: superjson, +// // The server needs to know your app's full url +// url: `http://localhost:3000/api/trpc`, +// /** +// * Set custom request headers on every request from tRPC +// * @see https://trpc.io/docs/v10/header +// */ +// headers() { +// if (!ctx?.req?.headers) { +// return {}; +// } +// // To use SSR properly, you need to forward client headers to the server +// // This is so you can pass through things like cookies when we're server-side rendering +// return { +// cookie: ctx.req.headers.cookie, +// }; +// }, +// }), +// ], +// }; +// }, +// }); +// export const trpcClient = trpc.createClient({ links: [] }); //server only?