diff --git a/.gitignore b/.gitignore index 4587401..fc26ffe 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ dist-ssr *.njsproj *.sln *.sw? +localhost-key.pem +localhost.pem diff --git a/.vscode/settings.json b/.vscode/settings.json index 37aec10..922775c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,21 @@ "editor.formatOnSave": true, "files.insertFinalNewline": true, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, // ESLint // ref: https://github.com/microsoft/vscode-eslint // plugin: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint diff --git a/package-lock.json b/package-lock.json index 46d6585..11b1729 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,19 @@ "name": "kuit-space-front", "version": "0.0.1", "dependencies": { + "@livekit/components-react": "^2.4.3", + "@livekit/components-styles": "^1.0.12", + "axios": "^1.7.3", + "choco": "^0.2.1", "es-hangul": "^1.4.5", + "livekit-client": "^2.4.2", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.24.1", "react-toastify": "^10.0.5", "styled-components": "^6.1.12", "styled-reset": "^4.5.2", + "vite-plugin-mkcert": "^1.17.5", "vite-plugin-svgr": "^4.2.0" }, "devDependencies": { @@ -438,6 +444,11 @@ "node": ">=6.9.0" } }, + "node_modules/@bufbuild/protobuf": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.10.0.tgz", + "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==" + }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", @@ -879,6 +890,28 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz", + "integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==", + "dependencies": { + "@floating-ui/utils": "^0.2.7" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", + "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz", + "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -979,6 +1012,61 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@livekit/components-core": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@livekit/components-core/-/components-core-0.11.2.tgz", + "integrity": "sha512-rXQ1OvyGe9gY8BCpH5FTr4Il17/sS/ecJQbG3PoOXAkQVl5JP965eqUPyKXZTdxNKlVLef00AygrO2pPArwOTA==", + "dependencies": { + "@floating-ui/dom": "1.6.8", + "loglevel": "1.9.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@livekit/protocol": "^1.16.0", + "livekit-client": "^2.4.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@livekit/components-react": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@livekit/components-react/-/components-react-2.4.3.tgz", + "integrity": "sha512-XhCvwFvNjhBJcoQHIY4Hk6MBp7mM9q0n0i7sN/xK3fB1DSjkxIkpc7lh/+Pjqdu6F6OJT3MjwNFYnftqy6kcmw==", + "dependencies": { + "@livekit/components-core": "0.11.2", + "clsx": "2.1.1", + "usehooks-ts": "3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@livekit/protocol": "^1.16.0", + "livekit-client": "^2.4.0", + "react": ">=18", + "react-dom": ">=18", + "tslib": "^2.6.2" + } + }, + "node_modules/@livekit/components-styles": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@livekit/components-styles/-/components-styles-1.0.12.tgz", + "integrity": "sha512-Hsxkfq240w0tMPtkQTHQotpkYfIY4lhP2pzegvOIIV/nYxj8LeRYypUjxJpFw3s6jQcV/WQS7oCYmFQdy98Jtw==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@livekit/protocol": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@livekit/protocol/-/protocol-1.20.0.tgz", + "integrity": "sha512-2RJQwzBa+MfUoy0zBWuyj8S2MTBxeTgREeG0r/1bNmkAFiBhsdgr87gIvblyqJxffUxJpALMu1Ee0M1XHX+9Ug==", + "peer": true, + "dependencies": { + "@bufbuild/protobuf": "^1.7.2" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1014,6 +1102,149 @@ "node": ">= 8" } }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", + "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", + "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", + "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", + "dependencies": { + "@octokit/request": "^8.3.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.1.tgz", + "integrity": "sha512-ryqobs26cLtM1kQxqeZui4v8FeznirUsksiA+RYemMPJ7Micju0WSkv50dBksTuZks9O5cg4wp+t8fZ/cLY56g==", + "dependencies": { + "@octokit/types": "^13.5.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.2.2.tgz", + "integrity": "sha512-EI7kXWidkt3Xlok5uN43suK99VWqc8OaIMktY9d9+RNKl69juoTyxmLoWPIZgJYzi41qj/9zU7G/ljnNOJ5AFA==", + "dependencies": { + "@octokit/types": "^13.5.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" + } + }, + "node_modules/@octokit/request": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", + "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", + "dependencies": { + "@octokit/endpoint": "^9.0.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", + "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/rest": { + "version": "20.1.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.1.tgz", + "integrity": "sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw==", + "dependencies": { + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.3.1", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.2.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz", + "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, "node_modules/@pkgr/core": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", @@ -2126,6 +2357,11 @@ "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2150,6 +2386,16 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", + "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -2162,6 +2408,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -2295,6 +2546,12 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/choco": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/choco/-/choco-0.2.1.tgz", + "integrity": "sha512-AurFOQn56J4Mxj1lilx6/Wl47kGfEm3ZpkGH9DnWlEYahJsX0ubj0pm5TobMpcPPJcQLtu98SBW2RdKB0l/4Dw==", + "deprecated": "unmaintained" + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -2321,6 +2578,17 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2524,6 +2792,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -3338,6 +3619,14 @@ "node": ">=0.10.0" } }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3460,6 +3749,25 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -3469,6 +3777,19 @@ "is-callable": "^1.1.3" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4254,6 +4575,29 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/livekit-client": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/livekit-client/-/livekit-client-2.4.2.tgz", + "integrity": "sha512-6iEeDiaon9TvH0L0t34wSApGk6In8Rpl538Dgh9hrxts2kq0scuxMTz2ipagFVIVGYOKceKBA2dnv/XOL+1ACw==", + "dependencies": { + "@livekit/protocol": "1.19.1", + "events": "^3.3.0", + "loglevel": "^1.8.0", + "sdp-transform": "^2.14.1", + "ts-debounce": "^4.0.0", + "tslib": "2.6.3", + "typed-emitter": "^2.1.0", + "webrtc-adapter": "^9.0.0" + } + }, + "node_modules/livekit-client/node_modules/@livekit/protocol": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@livekit/protocol/-/protocol-1.19.1.tgz", + "integrity": "sha512-PQYIuqRv++fRik9tKulJ0C0tT5O4cNviBA7OxwLTCBFDxJpve8ua8/JZ+nK+7r4j2KbLfVjsJYop9wcTCgRn7Q==", + "dependencies": { + "@bufbuild/protobuf": "^1.7.2" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4269,12 +4613,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, "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 }, + "node_modules/loglevel": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4324,6 +4685,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -4508,7 +4888,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -4735,6 +5114,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -4969,6 +5353,14 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-array-concat": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", @@ -5012,6 +5404,19 @@ "loose-envify": "^1.1.0" } }, + "node_modules/sdp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz", + "integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==" + }, + "node_modules/sdp-transform": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.2.tgz", + "integrity": "sha512-icY6jVao7MfKCieyo1AyxFYm1baiM+fA00qW/KrNNVlkxHAd34riEKuEkUe4bBb3gJwLJZM+xT60Yj1QL8rHiA==", + "bin": { + "sdp-verify": "checker.js" + } + }, "node_modules/semver": { "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", @@ -5366,6 +5771,11 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-debounce": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ts-debounce/-/ts-debounce-4.0.0.tgz", + "integrity": "sha512-+1iDGY6NmOGidq7i7xZGA4cm8DAa6fqdYcvO5Z6yBevH++Bdo9Qt/mN0TzHUgcCcKv1gmh9+W5dHqz8pMWbCbg==" + }, "node_modules/tsconfck": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.1.tgz", @@ -5512,6 +5922,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz", + "integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==", + "optionalDependencies": { + "rxjs": "*" + } + }, "node_modules/typescript": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", @@ -5546,6 +5964,11 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "devOptional": true }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==" + }, "node_modules/update-browserslist-db": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", @@ -5584,6 +6007,20 @@ "punycode": "^2.1.0" } }, + "node_modules/usehooks-ts": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-3.1.0.tgz", + "integrity": "sha512-bBIa7yUyPhE1BCc0GmR96VU/15l/9gP1Ch5mYdLcFBaFGQsdmXkvjV0TtOqW1yUd6VjIwDunm+flSciCQXujiw==", + "dependencies": { + "lodash.debounce": "^4.0.8" + }, + "engines": { + "node": ">=16.15.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/vite": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", @@ -5638,6 +6075,23 @@ } } }, + "node_modules/vite-plugin-mkcert": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-1.17.5.tgz", + "integrity": "sha512-KKGY3iHx/9zb7ow8JJ+nLN2HiNIBuPBwj34fJ+jAJT89/8qfk7msO7G7qipR8VDEm9xMCys0xT11QOJbZcg3/Q==", + "dependencies": { + "@octokit/rest": "^20.0.2", + "axios": "^1.6.8", + "debug": "^4.3.4", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=v16.7.0" + }, + "peerDependencies": { + "vite": ">=3" + } + }, "node_modules/vite-plugin-svgr": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.2.0.tgz", @@ -5670,6 +6124,18 @@ } } }, + "node_modules/webrtc-adapter": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-9.0.1.tgz", + "integrity": "sha512-1AQO+d4ElfVSXyzNVTOewgGT/tAomwwztX/6e3totvyyzXPvXIIuUUjAmyZGbKBKbZOXauuJooZm3g6IuFuiNQ==", + "dependencies": { + "sdp": "^3.2.0" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=3.10.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5732,8 +6198,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/yallist": { "version": "3.1.1", diff --git a/package.json b/package.json index a05de10..bdd3a70 100644 --- a/package.json +++ b/package.json @@ -11,13 +11,19 @@ "preview": "vite preview" }, "dependencies": { + "@livekit/components-react": "^2.4.3", + "@livekit/components-styles": "^1.0.12", + "axios": "^1.7.3", + "choco": "^0.2.1", "es-hangul": "^1.4.5", + "livekit-client": "^2.4.2", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.24.1", "react-toastify": "^10.0.5", "styled-components": "^6.1.12", "styled-reset": "^4.5.2", + "vite-plugin-mkcert": "^1.17.5", "vite-plugin-svgr": "^4.2.0" }, "devDependencies": { diff --git a/src/apis/LoginApi.ts b/src/apis/LoginApi.ts new file mode 100644 index 0000000..6754b1a --- /dev/null +++ b/src/apis/LoginApi.ts @@ -0,0 +1,30 @@ +import { createRequestOptionsJSON, RequestOptions } from "./_createRequestOptions"; + +const fetchLoginApi = async (url: string, options: RequestOptions) => { + const response = await fetch(url, options) + .then((res) => res.headers) + .catch((err) => console.error(err)); + + //console.log(response); + + return response; +}; + +export const loginApi = async (email: string, password: string) => { + const body = { + email: email, + password: password, + }; + + const requestOptions = createRequestOptionsJSON("POST", JSON.stringify(body)); + const response = await fetchLoginApi("https://project-space.xyz/user/login", requestOptions); + + // Authorization token 응답에 포함되면 local storage에 저장 + // if (response) { + // console.log(response); + // const temp = response.get("Authorization"); + // localStorage.setItem("Authorization", temp); + // } + + return response; +}; diff --git a/src/apis/Pay/PayPageAPI.ts b/src/apis/Pay/PayPageAPI.ts new file mode 100644 index 0000000..4df8abd --- /dev/null +++ b/src/apis/Pay/PayPageAPI.ts @@ -0,0 +1,99 @@ +import { PayReceiveInfo, PayRequestInfo } from "@/pages/PayPage/PayPage"; +import { + createRequestOptionsJSON, + RequestOptions, + createRequestOptionsJSON_AUTH, +} from "@/apis/_createRequestOptions"; +import { BankInfo } from "@/pages/PayPage/CreateRequestPage"; + +const fetchPayApi = async (url: string, options: RequestOptions) => { + const response = await fetch(url, options).catch((err) => console.error(err)); + return response; +}; + +export const payCompleteApi = async (TargetId: number) => { + const body = { + payRequestTargetId: TargetId, + }; + const requestOptions = createRequestOptionsJSON_AUTH("POST", JSON.stringify(body)); + if (!requestOptions) { + return null; + } + const response = await fetchPayApi( + `https://project-space.xyz/space/3/pay/complete`, + requestOptions, + ); +}; + +export const payReceiveApi = async ( + spaceID: number, + setCurrentData: React.Dispatch>, + setCompleteData: React.Dispatch>, +) => { + const requestOptions = createRequestOptionsJSON_AUTH("GET"); + if (!requestOptions) { + return null; + } + const response = await fetchPayApi(`/api/space/${spaceID}/pay/receive`, requestOptions); + + if (response) { + response.json().then((data) => { + setCurrentData(data.result.payReceiveInfoDtoListIncomplete); + setCompleteData(data.result.payReceiveInfoDtoListComplete); + }); + } +}; + +export const payRequestApi = async ( + spaceID: number, + setCurrentData: React.Dispatch>, + setCompleteData: React.Dispatch>, +) => { + const requestOptions = createRequestOptionsJSON_AUTH("GET"); + if (!requestOptions) { + return null; + } + const response = await fetchPayApi(`/api/space/${spaceID}/pay/request`, requestOptions); + + if (response) { + response.json().then((data) => { + setCurrentData(data.result.payRequestInfoDtoListInComplete); + setCompleteData(data.result.payRequestInfoDtoListComplete); + }); + } +}; +export const payHomeApi = async ( + spaceID: number, + setReqData: React.Dispatch>, + setRecData: React.Dispatch>, +) => { + const requestOptions = createRequestOptionsJSON_AUTH("GET"); + if (!requestOptions) { + return null; + } + const response = await fetchPayApi(`/api/space/${spaceID}/pay`, requestOptions); + + if (response) { + response.json().then((data) => { + setReqData(data.result.payRequestInfoDtoList); + setRecData(data.result.payReceiveInfoDtoList); + }); + } +}; + +export const recentAccountApi = async ( + spaceID: number, + setBankData: React.Dispatch>, +) => { + const requestOptions = createRequestOptionsJSON_AUTH("GET"); + if (!requestOptions) { + return null; + } + const response = await fetchPayApi(`/api/space/pay/recent-bank-info`, requestOptions); + + if (response) { + response.json().then((data) => { + setBankData(data.result.recentPayRequestBankInfoDtoList); + }); + } +}; diff --git a/src/apis/_createRequestOptions.ts b/src/apis/_createRequestOptions.ts new file mode 100644 index 0000000..de8cc89 --- /dev/null +++ b/src/apis/_createRequestOptions.ts @@ -0,0 +1,50 @@ +export interface RequestOptions { + method: "GET" | "POST"; + body?: BodyInit; + headers?: HeadersInit; + redirect?: RequestRedirect; +} + +export const createRequestOptionsJSON = ( + method: RequestOptions["method"], + body?: RequestOptions["body"], +): RequestOptions => { + return { + method: method, + body: body, + redirect: "follow", + headers: { + "Content-Type": "application/json", + }, + }; +}; + +// export const createRequestOptionsFORM = ( method: RequestOptions["method"], +// body: RequestOptions["body"], +// ): RequestOptions => ({ +// method: method, +// body: JSON.stringify(body), +// redirect: "follow", +// headers: { +// "Content-Type": "application/json", +// }, +// }); + +export const createRequestOptionsJSON_AUTH = ( + method: RequestOptions["method"], + body?: RequestOptions["body"], +): RequestOptions | null => { + const token = localStorage.getItem("Authorization"); + + return token + ? { + method: method, + body: body, + redirect: "follow", + headers: { + "Content-Type": "application/json", + Authorization: token, + }, + } + : null; +}; diff --git a/src/apis/apis.ts b/src/apis/apis.ts index 919dd2c..c5d60e4 100644 --- a/src/apis/apis.ts +++ b/src/apis/apis.ts @@ -1,3 +1,3 @@ export const apis = () => { - console.log("this is apis, add contents"); + console.log("this is apis, add contents"); }; diff --git a/src/apis/voiceroomApi.ts b/src/apis/voiceroomApi.ts new file mode 100644 index 0000000..cfca828 --- /dev/null +++ b/src/apis/voiceroomApi.ts @@ -0,0 +1,46 @@ +import { VrList } from "@/pages/VoiceRoomPage/VoiceRoomListPage"; +import { + createRequestOptionsJSON, + RequestOptions, + createRequestOptionsJSON_AUTH, +} from "@/apis/_createRequestOptions"; + +const fetchVrApi = async (url: string, options: RequestOptions) => { + const response = await fetch(url, options).catch((err) => console.error(err)); + return response; +}; + +export const VrListApi = async ( + spaceID: number, + setVRList: React.Dispatch>, +) => { + const requestOptions = createRequestOptionsJSON_AUTH("GET"); + if (!requestOptions) { + return null; + } + const response = await fetchVrApi(`/api/space/${spaceID}/voiceRoom`, requestOptions); + if (response) { + response.json().then((data) => { + setVRList(data.result.voiceRoomList); + }); + } +}; + +export const VrTokenApi = async (spaceID: number, VrID: number) => { + const requestOptions = createRequestOptionsJSON_AUTH("GET"); + if (!requestOptions) { + return null; + } + const response = await fetchVrApi( + `/api/space/${spaceID}/voiceRoom/${VrID}/token`, + requestOptions, + ); + if (response) { + response.json().then((data) => { + const tmp = response.headers.get("Authorization"); + if (tmp) { + localStorage.setItem("VrToken", tmp); + } + }); + } +}; diff --git a/src/pages/LoginPage/LoginPage.tsx b/src/pages/LoginPage/LoginPage.tsx index b4572f7..2014812 100644 --- a/src/pages/LoginPage/LoginPage.tsx +++ b/src/pages/LoginPage/LoginPage.tsx @@ -1,50 +1,80 @@ import React, { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; -import { Container, Logo, Input, LoginButton, BtContainer, Button, ScContainer, Social } from "@/pages/LoginPage/LoginPage.styled.ts"; +import { + Container, + Logo, + Input, + LoginButton, + BtContainer, + Button, + ScContainer, + Social, +} from "@/pages/LoginPage/LoginPage.styled.ts"; import logoSpace from "@/assets/logo_space.svg"; import kakao from "@/assets/Login/icon_kakao.svg"; import google from "@/assets/Login/icon_google.svg"; import naver from "@/assets/Login/icon_naver.svg"; +import { loginApi } from "@/apis/LoginApi"; const LoginPage = () => { - const navigate = useNavigate(); + const navigate = useNavigate(); - const [id, setId] = useState(""); - const [password, setPassword] = useState(""); - const [isButtonActive, setIsButtonActive] = useState(false); + const [id, setId] = useState(""); + const [password, setPassword] = useState(""); + const [isButtonActive, setIsButtonActive] = useState(false); + const handleLogin = () => { + loginApi(id, password); + }; + useEffect(() => { + setIsButtonActive(id.trim() !== "" && password.trim() !== ""); + }, [id, password]); - useEffect(() => { - setIsButtonActive(id.trim() !== "" && password.trim() !== ""); - }, [id, password]); - - return ( - <> - - - Logo - - setId(e.target.value)} style={{ marginTop: "10.37rem" }} /> - setPassword(e.target.value)} /> - 로그인 - - - - - - - - kakao - - - google - - - naver - - - - - ); + return ( + <> + + + Logo + + setId(e.target.value)} + style={{ marginTop: "10.37rem" }} + /> + setPassword(e.target.value)} + /> + { + handleLogin(); + }} + > + 로그인 + + + + + + + + + kakao + + + google + + + naver + + + + + ); }; export default LoginPage; diff --git a/src/pages/PayPage/CompleteReqDataDiv.tsx b/src/pages/PayPage/CompleteReqDataDiv.tsx new file mode 100644 index 0000000..c909df7 --- /dev/null +++ b/src/pages/PayPage/CompleteReqDataDiv.tsx @@ -0,0 +1,41 @@ +import * as s from "@/pages/PayPage/PayPage.styled"; +import { NormalBtn } from "./NormalBtn"; +import reactIcon from "@/assets/react.svg"; +import { useEffect, useState } from "react"; +import { DarkNormalBtn } from "./DarkNormalBtn"; + +import { ToastContainer, toast } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; +import { PayReceiveInfo, addComma } from "./PayPage"; +import { GrayBtn } from "./GrayBtn"; + +const ReqDataDiv = ({ data }: { data: PayReceiveInfo }) => { + // useEffect(() => { + // console.log(data); + // }, []); + // true : 송금하기 false : 송금완료 + const [chk, setChk] = useState(true); + const price = addComma(data.requestAmount); + + return ( + + + + {data.payCreatorName} + + {price}원 + + +
+ 송금하기 +
+
+ ); +}; + +export default ReqDataDiv; diff --git a/src/pages/PayPage/CreatePayComponents.tsx b/src/pages/PayPage/CreatePayComponents.tsx index 766c6c2..8731db1 100644 --- a/src/pages/PayPage/CreatePayComponents.tsx +++ b/src/pages/PayPage/CreatePayComponents.tsx @@ -18,6 +18,7 @@ const PayChatMemberDiv = () => { 시험 + ); }; diff --git a/src/pages/PayPage/CreateRequestPage.tsx b/src/pages/PayPage/CreateRequestPage.tsx index 82cff27..20e6e36 100644 --- a/src/pages/PayPage/CreateRequestPage.tsx +++ b/src/pages/PayPage/CreateRequestPage.tsx @@ -2,7 +2,7 @@ import TopBarText, { LeftEnum } from "@/components/TopBarText"; import * as s from "@/pages/PayPage/PayPage.styled"; import Kookmin from "@/assets/PayPage/test_bank.svg"; import { BottomBtn } from "@/components/BottomBtn"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import CompletePay from "./CompletePay"; import CompleteCreatePay from "./CompleteCreatePay"; import CheckBox from "@/components/CheckBox"; @@ -10,23 +10,33 @@ import { Member } from "../ChatPage/ChatCreatePage/ChatCreatePage.styled"; import ReactImg from "@/assets/react.svg"; import { PayChatDiv } from "./CreatePayComponents"; import SearchIcon from "@/assets/PayPage/search_icon.svg"; +import { recentAccountApi } from "@/apis/Pay/PayPageAPI"; -const RecentAccountDiv = () => { +const RecentAccountDiv = ({ data }: { data: BankInfo }) => { return ( - 국민은행 - 123-1234-12345 + {data.bankName} + {data.bankAccountNum} ); }; +export type BankInfo = { + bankName: String; + bankAccountNum: String; +}; type NextPageType = { nextPage: Function; }; + const CreateRequestPage1 = ({ nextPage }: NextPageType) => { + const [bankData, setBankData] = useState([]); + useEffect(() => { + recentAccountApi(3, setBankData); + }, []); return ( <> @@ -47,7 +57,9 @@ const CreateRequestPage1 = ({ nextPage }: NextPageType) => {
최근 정산받은 계좌 - + {bankData?.map((value, index) => { + return ; + })}
@@ -88,7 +100,8 @@ const CreateRequestPage2 = ({ nextPage }: NextPageType) => { 정산할 멤버를 선택해주세요 {menuArr.map((value, index) => ( -
  • selectMenuHandler(index)} > @@ -99,7 +112,12 @@ const CreateRequestPage2 = ({ nextPage }: NextPageType) => { {tabIndex == 0 ? (
    {chatroomArr.map((value, index) => ( - + ))}
    ) : ( diff --git a/src/pages/PayPage/GrayMyReqDataDiv.tsx b/src/pages/PayPage/GrayMyReqDataDiv.tsx index b6b4bc8..6a18d4f 100644 --- a/src/pages/PayPage/GrayMyReqDataDiv.tsx +++ b/src/pages/PayPage/GrayMyReqDataDiv.tsx @@ -1,20 +1,25 @@ import * as s from "@/pages/PayPage/PayPage.styled"; +import { PayRequestInfo } from "./PayPage"; +import { addComma } from "./PayPage"; -const GrayMyReqDataDiv = () => { - return ( - - - - 5명 정산완료 - - 40000원 - / 60000원 - - - 이미지 넣어야댐 - - - ); +const GrayMyReqDataDiv = ({ data }: { data: PayRequestInfo }) => { + const num = data.totalTargetNum - data.receiveTargetNum; + const price1 = addComma(data.receiveAmount); + const price2 = addComma(data.totalAmount); + return ( + + + + {num}명 정산완료 + + {price1}원  + / {price2}원 + + + 이미지 넣어야댐 + + + ); }; export default GrayMyReqDataDiv; diff --git a/src/pages/PayPage/MyReqDataDiv.tsx b/src/pages/PayPage/MyReqDataDiv.tsx index 492e5f8..783b09e 100644 --- a/src/pages/PayPage/MyReqDataDiv.tsx +++ b/src/pages/PayPage/MyReqDataDiv.tsx @@ -1,20 +1,26 @@ import * as s from "@/pages/PayPage/PayPage.styled"; +import { PayRequestInfo } from "./PayPage"; +import { addComma } from "./PayPage"; -const MyReqDataDiv = () => { - return ( - - - - 정산 완료까지 2명 남았어요 - - 40000원 - / 60000원 - - - 이미지 넣어야댐 - - - ); +const MyReqDataDiv = ({ data }: { data: PayRequestInfo }) => { + const num = data.totalTargetNum - data.receiveTargetNum; + const price1 = addComma(data.receiveAmount); + const price2 = addComma(data.totalAmount); + + return ( + + + + 정산 완료까지 {num}명 남았어요 + + {price1}원  + / {price2}원 + + + 이미지 넣어야댐 + + + ); }; export default MyReqDataDiv; diff --git a/src/pages/PayPage/MyRequestPayPage.tsx b/src/pages/PayPage/MyRequestPayPage.tsx index 2281aa0..648ef78 100644 --- a/src/pages/PayPage/MyRequestPayPage.tsx +++ b/src/pages/PayPage/MyRequestPayPage.tsx @@ -1,14 +1,23 @@ import TopBarText, { LeftEnum } from "@/components/TopBarText"; import * as s from "@/pages/PayPage/PayPage.styled"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import MyReqDataDiv from "./MyReqDataDiv"; import GrayMyReqDataDiv from "./GrayMyReqDataDiv"; import { useParams } from "react-router-dom"; import PayResult from "./PayResult"; +import { PayRequestInfo } from "./PayPage"; +import { payRequestApi } from "@/apis/Pay/PayPageAPI"; const MyRequestPayPage = () => { const [tabIndex, setTabIndex] = useState(0); + const [currentData, setCurrentData] = useState([]); + const [completeData, setCompleteData] = useState([]); + + const spaceID = 3; + useEffect(() => { + payRequestApi(spaceID, setCurrentData, setCompleteData); + }, []); const menuArr = [ { name: "미정산", content: "Tab menu ONE" }, { name: "정산완료", content: "Tab menu TWO" }, @@ -28,11 +37,15 @@ const MyRequestPayPage = () => {
    진행 중인 정산 - + {currentData?.map((value) => { + return ; + })}
    완료된 정산 - + {completeData?.map((value) => { + return ; + })}
    ) : ( @@ -47,7 +60,8 @@ const MyRequestPayPage = () => { {menuArr.map((value, index) => ( -
  • selectMenuHandler(index)} > diff --git a/src/pages/PayPage/PayPage.tsx b/src/pages/PayPage/PayPage.tsx index 06bdf9e..c4e633c 100644 --- a/src/pages/PayPage/PayPage.tsx +++ b/src/pages/PayPage/PayPage.tsx @@ -3,9 +3,90 @@ import { GradientBtn } from "@/pages/PayPage/GradientBtn"; import right from "@/assets/PayPage/arrow_right.svg"; import * as s from "@/pages/PayPage/PayPage.styled"; import { useNavigate } from "react-router-dom"; +import { useEffect, useState } from "react"; +import axios from "axios"; +import { payCompleteApi, payHomeApi } from "@/apis/Pay/PayPageAPI"; +const SpaceID = 3; + +export const addComma = (price: number) => { + let returnString = price?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); + return returnString; +}; + +export type PayRequestInfo = { + payRequestId: number; + receiveAmount: number; + receiveTargetNum: number; + totalAmount: number; + totalTargetNum: number; +}; + +export type PayReceiveInfo = { + payRequestTargetId: number; + payCreatorName: string; + requestAmount: number; +}; + +const PayRequestInfo = ({ data }: { data: PayRequestInfo }) => { + const res: number = data.totalTargetNum - data.receiveAmount; + return ( + + + {data.receiveAmount}원 + /{data.totalAmount}원 + + 정산완료까지 {res}명 남았어요 + + ); +}; + +const PayReceiveInfo = ({ data }: { data: PayReceiveInfo }) => { + return ( + + {data.payCreatorName}님이 정산을 요청했어요 + {data.requestAmount}원 + + ); +}; + +// function RequestPayInfo( +// setReqData: React.Dispatch>, +// setRecData: React.Dispatch>, +// ) { +// const response = fetch("/api/space/3/pay", { +// method: "GET", +// headers: { +// "Content-Type": "application/json", +// Authorization: +// "Bearer eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MjM1MDcyNjYsImV4cCI6MTcyMzUxMDg2NiwidXNlcklkIjo1M30.qtOD23WXy5y4Rn6rk1mp1Q6CcgcEEdhB7Vq7udwakmk", +// }, +// }) +// .then((res) => res.json()) +// .then((data) => { +// setReqData(data.result.payRequestInfoDtoList); +// setRecData(data.result.payReceiveInfoDtoList); +// }); +// } const PayPage = () => { + const [reqData, setReqData] = useState([]); + const [recData, setRecData] = useState([]); + + useEffect(() => { + //임시 + localStorage.setItem( + "Authorization", + "Bearer eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MjM2MTcyMjksImV4cCI6MTcyMzYyMDgyOSwidXNlcklkIjo1M30.D5EODMkyPJkfSllif-ALtOlJU355MqKWzC2FMg_nwbw", + ); + payHomeApi(SpaceID, setReqData, setRecData); + // RequestPayInfo(setReqData, setRecData); + }, []); + const navigator = useNavigate(); + const data = { + payRequestTargetId: 1, + }; + return ( <> @@ -27,16 +108,9 @@ const PayPage = () => { {/* */} - - {/* 컴포넌트화 예정 */} - - - 30,000원 - /45,000원 - - 정산완료까지 1명 남았어요 - - {/* 컴포넌트화 예정 */} + {reqData?.map((value) => { + return ; + })} { @@ -49,12 +123,10 @@ const PayPage = () => { {/* */} - {/* 컴포넌트화 예정 */} - - 김민지 님이 정산을 요청했어요 - 15,000원 - - {/* 컴포넌트화 예정 */} + {recData?.map((value) => { + console.log(value); + return ; + })} diff --git a/src/pages/PayPage/ReqDataDiv.tsx b/src/pages/PayPage/ReqDataDiv.tsx index d3bebda..4d29dfb 100644 --- a/src/pages/PayPage/ReqDataDiv.tsx +++ b/src/pages/PayPage/ReqDataDiv.tsx @@ -1,64 +1,100 @@ import * as s from "@/pages/PayPage/PayPage.styled"; import { NormalBtn } from "./NormalBtn"; import reactIcon from "@/assets/react.svg"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { DarkNormalBtn } from "./DarkNormalBtn"; import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; +import { PayReceiveInfo, addComma } from "./PayPage"; +import { GradientBtn } from "./GradientBtn"; +import check from "@/assets/PayPage/check.svg"; +import { payCompleteApi } from "@/apis/Pay/PayPageAPI"; -const ReqDataDiv = () => { - // true : 송금하기 false : 송금완료 - const [chk, setChk] = useState(true); +const ReqDataDiv = ({ data }: { data: PayReceiveInfo }) => { + const spaceID = 3; - const copyToClipboard = async (text: string) => { - try { - await navigator.clipboard.writeText(text); - toast.success("클립보드에 계좌번호가 복사되었습니다!", { - position: "bottom-center", - autoClose: 3000, - hideProgressBar: false, - closeOnClick: true, - pauseOnHover: true, - draggable: true, - progress: undefined, - theme: "dark", - }); - } catch (e) { - alert(e); - } - }; - const onPayClick = () => { - setChk(!chk); - //모달 생성 - //클립보드 복사 - copyToClipboard("씨앗은행 1231109999"); - }; - const onCompleteClick = () => { - setChk(!chk); - //모달 생성 - //클립보드 복사 - }; - return ( - - - - 박규환 - 15,000원 - -
    - {chk ? ( - - 송금하기 - - ) : ( - - 송금완료 - - )} -
    -
    - ); + useEffect(() => { + console.log(data); + }, []); + // true : 송금하기 false : 송금완료 + const [chk, setChk] = useState(0); + const price = addComma(data.requestAmount); + + const nextChk = () => { + setChk(chk + 1); + chk % 3; + }; + + const copyToClipboard = async (text: string) => { + try { + await navigator.clipboard.writeText(text); + toast.success("클립보드에 계좌번호가 복사되었습니다!", { + position: "bottom-center", + autoClose: 3000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + theme: "dark", + }); + } catch (e) { + alert(e); + } + }; + + const onPayClick = () => { + nextChk(); + //모달 생성 + //클립보드 복사 + copyToClipboard("씨앗은행 1231109999"); + }; + + const onCompleteClick = () => { + nextChk(); + payCompleteApi(data.payRequestTargetId); + //모달 생성 + //클립보드 복사 + }; + + const statusSwitch = () => { + switch (chk) { + case 0: + return ( + + 송금하기 + + ); + case 1: + return ( + + 송금완료 + + ); + case 2: + return ( + + 송금완료 + + + ); + } + }; + return ( + + + + {data.payCreatorName} + + {price}원 + + +
    {statusSwitch()}
    +
    + ); }; export default ReqDataDiv; diff --git a/src/pages/PayPage/RequestedPayPage.tsx b/src/pages/PayPage/RequestedPayPage.tsx index 9d13cff..0f09a5a 100644 --- a/src/pages/PayPage/RequestedPayPage.tsx +++ b/src/pages/PayPage/RequestedPayPage.tsx @@ -6,41 +6,47 @@ import { GrayBtn } from "./GrayBtn"; import ReqDataDiv from "./ReqDataDiv"; import { ToastContainer } from "react-toastify"; import { Transform } from "stream"; +import { useEffect, useState } from "react"; +import { payReceiveApi } from "@/apis/Pay/PayPageAPI"; +import { PayReceiveInfo } from "./PayPage"; +import CompleteReqDataDiv from "./CompleteReqDataDiv"; const RequestedPayPage = () => { - return ( - <> - - - 진행 중인 정산 - - 완료된 정산 - - - - 박규환 - 15,000원 - -
    - 송금하기 -
    -
    - -
    - - ); + const [currentData, setCurrentData] = useState([]); + const [completeData, setCompleteData] = useState([]); + useEffect(() => { + payReceiveApi(3, setCurrentData, setCompleteData); + }, []); + return ( + <> + + + 진행 중인 정산 + {currentData?.map((value) => { + return ; + })} + 완료된 정산 + {currentData?.map((value) => { + return ( + + ); + })} + + + + ); }; export default RequestedPayPage; diff --git a/src/pages/VoiceRoomPage/JoinVoiceRoomPage.tsx b/src/pages/VoiceRoomPage/JoinVoiceRoomPage.tsx index 28f4880..d5e9c21 100644 --- a/src/pages/VoiceRoomPage/JoinVoiceRoomPage.tsx +++ b/src/pages/VoiceRoomPage/JoinVoiceRoomPage.tsx @@ -6,53 +6,65 @@ import redo from "@/assets/icon_redo.svg"; //임시로 적용하는 프로필 이미지 import reactLogo from "@/assets/react.svg"; import { BottomBtn } from "@/components/BottomBtn"; -import { useNavigate } from "react-router-dom"; +import { useLocation, useNavigate } from "react-router-dom"; import { useState } from "react"; import VoiceRoomPage from "./VoiceRoomPage"; +import { VrList } from "./VoiceRoomListPage"; +import { VrTokenApi } from "@/apis/voiceroomApi"; const JoinVoiceRoomPage = () => { - const title = "작업 안 하면 죽는 방"; - const user_num = 6; - const userProfile = reactLogo; - const userName = "박가온"; - - const [isJoined, setJoin] = useState(false); - const [vrCode, setvrCode] = useState("테스트 보이스룸"); - - const navigate = useNavigate(); - return ( -
    - {isJoined ? ( - <> - - - ) : ( - <> - - - - {title} - - - - - - - -
    {userName}
    - { - setJoin(true); - }} - > - 참여하기 - -
    - - )} -
    - ); + const location = useLocation(); + const data: VrList = location.state; + + const title = data.name; + const user_num = data.numParticipant; + + // 프로필 수정 + const userProfile = reactLogo; + + // 임시 이름 + const userName = "임시"; + + const [isJoined, setJoin] = useState(false); + + const onJoin = () => { + setJoin(true); + VrTokenApi(3, data.id); + }; + const navigate = useNavigate(); + return ( +
    + {isJoined ? ( + <> + + + ) : ( + <> + + + + {title} + + + + + + + +
    {userName}
    + { + onJoin(); + }} + > + 참여하기 + +
    + + )} +
    + ); }; export default JoinVoiceRoomPage; diff --git a/src/pages/VoiceRoomPage/VoiceRoomListPage.styled.ts b/src/pages/VoiceRoomPage/VoiceRoomListPage.styled.ts index c3dc660..d744872 100644 --- a/src/pages/VoiceRoomPage/VoiceRoomListPage.styled.ts +++ b/src/pages/VoiceRoomPage/VoiceRoomListPage.styled.ts @@ -4,95 +4,96 @@ import yellow from "@/assets/VoiceRoom/yellow_gradient.svg"; import purple from "@/assets/VoiceRoom/purple_gradient.svg"; export const DropdownDiv = styled.div` - display: flex; - flex-direction: column; - justify-content: center; - visibility: hidden; - z-index: 1; - color: var(--Foundation-Gray-white, #fff); - margin: 0rem 0rem 0.5rem 1rem; - padding: 1rem; - width: 7.5rem; + display: flex; + flex-direction: column; + justify-content: center; + visibility: hidden; + z-index: 1; + color: var(--Foundation-Gray-white, #fff); + margin: 0rem 0rem 0.5rem 1rem; + padding: 1rem; + width: 7.5rem; - /* text/Regular 14pt */ - font-family: Freesentation; - font-size: 0.875rem; - font-style: normal; - font-weight: 400; - line-height: 140%; /* 19.6px */ - letter-spacing: 0.035rem; - border-radius: 0.75rem; - background: var(--GRAY-800, #222226); + /* text/Regular 14pt */ + font-family: Freesentation; + font-size: 0.875rem; + font-style: normal; + font-weight: 400; + line-height: 140%; /* 19.6px */ + letter-spacing: 0.035rem; + border-radius: 0.75rem; + background: var(--GRAY-800, #222226); `; export const ActiveP = styled.p` - font-family: "Freesentation SB"; - font-size: 1.125rem; + font-family: "Freesentation SB"; + font-size: 1.125rem; `; export const VRTitleDiv = styled.div` - font-family: "Freesentation SB"; - font-size: 1.25rem; - color: black; - margin: 1rem; + font-family: "Freesentation SB"; + font-size: 1.25rem; + color: black; + margin: 1rem; `; export const InfoDiv = styled.div` - display: flex; - flex-direction: column; - &:hover ${DropdownDiv} { - visibility: visible; - } + display: flex; + flex-direction: column; + &:hover ${DropdownDiv} { + visibility: visible; + } `; export const BGdiv = styled.div` - display: flex; - flex-direction: column; - background-image: url(${yellow}); + display: flex; + flex-direction: column; + border-radius: 12px; + background: linear-gradient(99deg, #fefc9e 6.74%, #f09b56 94.48%); - width: 100%; + width: 100%; `; export const BGdiv2 = styled.div` - display: flex; - justify-content: left; - background-image: url(${purple}); - background-repeat: no-repeat; - background-size: cover; - width: 100%; - height: 15.5rem; + display: flex; + justify-content: left; + background-image: url(${purple}); + background-repeat: no-repeat; + background-size: cover; + width: 100%; + height: 15.5rem; `; export const RoundDiv = styled.div` - background-color: #222226; - border-radius: 1.25rem; - padding: 0.25rem 0.75rem 0.25rem 0.375rem; - margin: 0.25rem 0rem 0.5rem 1rem; - font-size: 0.875rem; - font-family: "Freesentation M"; - color: "#767681"; - width: 7.5rem; + background-color: #222226; + border-radius: 1.25rem; + padding: 0.25rem 0.75rem 0.25rem 0.375rem; + margin: 0.25rem 0rem 0.5rem 1rem; + font-size: 0.875rem; + font-family: "Freesentation M"; + color: "#767681"; + width: 7.5rem; `; export const RoundDiv2 = styled.div` - background-color: #222226; - border-radius: 1.25rem; - padding: 0.875rem 1rem 0.875rem 1rem; - font-size: 0.875rem; - font-family: "Freesentation M"; - color: "#767681"; - margin: 0.625rem 0rem 0.625rem 0rem; + background-color: #222226; + border-radius: 1.25rem; + padding: 0.875rem 1rem 0.875rem 1rem; + font-size: 0.875rem; + font-family: "Freesentation M"; + color: "#767681"; + margin: 0.625rem 0rem 0.625rem 0rem; `; export const StyledButton = styled.button` - background-color: #171719; - border-radius: 0.75rem; - border: 0.0625rem solid #767681; - padding: 1rem 0rem 1rem 0rem; - margin: 0.875rem 0rem 1.25rem 0rem; - color: #d4d4d9; + background-color: #171719; + border-radius: 0.75rem; + border: 0.0625rem solid #767681; + padding: 1rem 0rem 1rem 0rem; + margin: 0.875rem 0rem 1.25rem 0rem; + color: #d4d4d9; - width: 100%; - font-size: 1.5rem; - font-family: "Freesentation M"; + width: 100%; + font-size: 1.5rem; + font-family: "Freesentation M"; `; export const StyledDiv = styled.div` - width: "100%"; - margin: "auto"; + width: "100%"; + margin: "auto"; `; diff --git a/src/pages/VoiceRoomPage/VoiceRoomListPage.tsx b/src/pages/VoiceRoomPage/VoiceRoomListPage.tsx index 8d38f8c..f91ad4c 100644 --- a/src/pages/VoiceRoomPage/VoiceRoomListPage.tsx +++ b/src/pages/VoiceRoomPage/VoiceRoomListPage.tsx @@ -1,67 +1,92 @@ import TopBarText from "@/components/TopBarText"; import { LeftEnum } from "@/components/TopBarText"; -import yellow from "@/assets/VoiceRoom/yellow_gradient.svg"; -import purple from "@/assets/VoiceRoom/purple_gradient.svg"; import plus from "@/assets/VoiceRoom/icon_plus.svg"; import styled from "styled-components"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; -import Data from "@/pages/VoiceRoomPage/testDB.json"; import * as s from "@/pages/VoiceRoomPage/VoiceRoomListPage.styled"; -import VoiceRoomUser from "./VoiceRoomUser"; +import { VrListApi } from "@/apis/voiceroomApi"; + +export type participantInfo = { + name: string; + profileImage: string; + mute: boolean; +}; + +export type VrList = { + active: boolean; + id: number; + name: string; + numParticipant: number; + order: number; + participantInfoList: participantInfo[]; +}; function voiceRoomList() { - const [arr, setArr] = useState([]); - const checkHandler = () => { - //fetch list - }; + const checkHandler = () => { + //fetch list + }; } -function memberList() {} +const VoiceRoomPortal = ({ vrList }: { vrList: VrList }) => { + const navigate = useNavigate(); + return ( +
    + { + navigate("/joinvoiceroom", { state: vrList }); + }} + > + {vrList.name} + + 대화 중인 스페이서 {vrList.active}명 + + {/* {vrList === undefined ? ( +
    dd
    + ) : ( + vrList.map((value, index) => { + return ; + }) + )} */} +
    +
    +
    +
    + ); +}; const VoiceRoomListPage = () => { - const navigate = useNavigate(); - return ( -
    - - 활동 중인 보이스룸 - { - navigate("/joinvoiceroom"); - }} - > - {"보이스룸 1"} - {/*
    ([]); + const [vrUserInfo, setVrUserInfo] = useState([]); + useEffect(() => { + VrListApi(3, setVrList); + }, []); + const navigate = useNavigate(); + return ( +
    + + 활동 중인 보이스룸 + {vrList?.map((value, index) => { + return ; + })} - style={{ display: "flex", alignItems: "center", width: "640px", height: "124px", marginLeft: "16px" }} - > */} - - 대화 중인 스페이서 6명 - - {Data.users.map((value, index) => { - return ; - })} - - - {/*
    */} - - 아무도 없어요! - 보이스룸 3 - 보이스룸 4 -
    - -
    { - navigate("/createvoiceroom"); - }} - > - - 새로 만들기 -
    -
    -
    -
    - ); + 아무도 없어요! + 보이스룸 3 + 보이스룸 4 +
    + +
    { + navigate("/createvoiceroom"); + }} + > + + 새로 만들기 +
    +
    +
    +
    + ); }; export default VoiceRoomListPage; diff --git a/src/pages/VoiceRoomPage/VoiceRoomPage.tsx b/src/pages/VoiceRoomPage/VoiceRoomPage.tsx index df65010..a2e6f1e 100644 --- a/src/pages/VoiceRoomPage/VoiceRoomPage.tsx +++ b/src/pages/VoiceRoomPage/VoiceRoomPage.tsx @@ -4,32 +4,77 @@ import plus from "@/assets/VoiceRoom/icon_plus.svg"; import back from "@/assets/icon_back.svg"; import setting from "@/assets/VoiceRoom/icon_setting.svg"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import * as s from "@/pages/VoiceRoomPage/VoiceRoomListPage.styled"; import * as sty from "@/components/TopBarText.styled"; -const VoiceRoomPage = ({ VoiceRoomName, setJoin }: { VoiceRoomName: string; setJoin: React.Dispatch> }) => { - const navigate = useNavigate(); - return ( -
    - - { - setJoin(false); - }} - > - - - - {VoiceRoomName} - - - - - -
    - ); +import { + ControlBar, + GridLayout, + LiveKitRoom, + ParticipantTile, + RoomAudioRenderer, + useTracks, +} from "@livekit/components-react"; +import "@livekit/components-styles"; +import { Track } from "livekit-client"; + +const VoiceRoomPage = ({ + VoiceRoomName, + setJoin, +}: { + VoiceRoomName: string; + setJoin: React.Dispatch>; +}) => { + const navigate = useNavigate(); + const [token, setToken] = useState(""); + useEffect(() => { + const temp = localStorage.getItem("VrToken"); + if (temp) { + const temp2 = temp.substring(7); + setToken(temp2); + console.log(temp2); + } else { + setToken(""); + } + }, []); + return ( +
    + + { + setJoin(false); + }} + > + + + + {VoiceRoomName} + + + + + +
    + + {/* The RoomAudioRenderer takes care of room-wide audio for you. */} + + {/* Controls for the user to start/stop audio, video, and screen + share tracks and to leave the room. */} + + +
    +
    + ); }; export default VoiceRoomPage; diff --git a/src/pages/VoiceRoomPage/VoiceRoomUser.tsx b/src/pages/VoiceRoomPage/VoiceRoomUser.tsx index 6c94d30..e5a9d03 100644 --- a/src/pages/VoiceRoomPage/VoiceRoomUser.tsx +++ b/src/pages/VoiceRoomPage/VoiceRoomUser.tsx @@ -1,24 +1,18 @@ import * as s from "@/pages/VoiceRoomPage/VoiceRoomUser.styled"; import micON from "@/assets/VoiceRoom/icon_microphone_ON.svg"; import micOFF from "@/assets/VoiceRoom/icon_microphone_OFF.svg"; +import { participantInfo } from "./VoiceRoomListPage"; -type vrUser = { - id: number; - name: string; - profile: string; - isMicON: boolean; -}; - -const VoiceRoomUser = ({ props }: { props: vrUser }) => { - return ( - - - -
    {props.name}
    - -
    -
    - ); +const VoiceRoomUser = ({ props }: { props: participantInfo[] }) => { + return ( + + + {/* +
    {props.name}
    + */} +
    +
    + ); }; export default VoiceRoomUser; diff --git a/vite.config.ts b/vite.config.ts index ebe3f4c..11e8cae 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,10 +2,12 @@ import react from "@vitejs/plugin-react-swc"; import * as path from "path"; import { defineConfig } from "vite"; import vitePluginSvgr from "vite-plugin-svgr"; +import mkcert from "vite-plugin-mkcert"; +import fs from "fs"; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react(), vitePluginSvgr()], + plugins: [react(), vitePluginSvgr(), mkcert()], resolve: { alias: { "@": path.resolve(__dirname, "./src"), @@ -17,4 +19,18 @@ export default defineConfig({ }, }, base: "/KUIT-Space-front/", + server: { + https: { + key: fs.readFileSync("localhost-key.pem"), + cert: fs.readFileSync("localhost.pem"), + }, + proxy: { + "/api": { + target: "https://project-space.xyz/", + changeOrigin: true, + // 요청 경로에서 '/api' 제거 + rewrite: (path) => path.replace(/^\/api/, ""), + }, + }, + }, });