diff --git a/blip-project/.gitignore b/blip-project/.gitignore index a547bf3..7ceb59f 100644 --- a/blip-project/.gitignore +++ b/blip-project/.gitignore @@ -22,3 +22,4 @@ dist-ssr *.njsproj *.sln *.sw? +.env diff --git a/blip-project/index.html b/blip-project/index.html index 0c589ec..b9bb266 100644 --- a/blip-project/index.html +++ b/blip-project/index.html @@ -1,8 +1,7 @@ - + - Vite + React diff --git a/blip-project/jsconfig.json b/blip-project/jsconfig.json new file mode 100644 index 0000000..b0db63d --- /dev/null +++ b/blip-project/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src"] +} diff --git a/blip-project/package-lock.json b/blip-project/package-lock.json index 91180b5..3ae3aeb 100644 --- a/blip-project/package-lock.json +++ b/blip-project/package-lock.json @@ -8,10 +8,15 @@ "name": "blip-project", "version": "0.0.0", "dependencies": { + "apexcharts": "^4.5.0", + "http-proxy-middleware": "^3.0.3", + "lib-jitsi-meet": "^1.0.6", "react": "^18.3.1", + "react-apexcharts": "^1.7.0", "react-dom": "^18.3.1", "react-router-dom": "^7.1.3", - "styled-components": "^6.1.14" + "simple-peer": "^9.11.1", + "styled-components": "^6.1.15" }, "devDependencies": { "@eslint/js": "^9.17.0", @@ -1207,6 +1212,62 @@ "win32" ] }, + "node_modules/@svgdotjs/svg.draggable.js": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.draggable.js/-/svg.draggable.js-3.0.6.tgz", + "integrity": "sha512-7iJFm9lL3C40HQcqzEfezK2l+dW2CpoVY3b77KQGqc8GXWa6LhhmX5Ckv7alQfUXBuZbjpICZ+Dvq1czlGx7gA==", + "license": "MIT", + "peerDependencies": { + "@svgdotjs/svg.js": "^3.2.4" + } + }, + "node_modules/@svgdotjs/svg.filter.js": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.filter.js/-/svg.filter.js-3.0.8.tgz", + "integrity": "sha512-YshF2YDaeRA2StyzAs5nUPrev7npQ38oWD0eTRwnsciSL2KrRPMoUw8BzjIXItb3+dccKGTX3IQOd2NFzmHkog==", + "license": "MIT", + "dependencies": { + "@svgdotjs/svg.js": "^3.1.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@svgdotjs/svg.js": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.2.4.tgz", + "integrity": "sha512-BjJ/7vWNowlX3Z8O4ywT58DqbNRyYlkk6Yz/D13aB7hGmfQTvGX4Tkgtm/ApYlu9M7lCQi15xUEidqMUmdMYwg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Fuzzyma" + } + }, + "node_modules/@svgdotjs/svg.resize.js": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.resize.js/-/svg.resize.js-2.0.5.tgz", + "integrity": "sha512-4heRW4B1QrJeENfi7326lUPYBCevj78FJs8kfeDxn5st0IYPIRXoTtOSYvTzFWgaWWXd3YCDE6ao4fmv91RthA==", + "license": "MIT", + "engines": { + "node": ">= 14.18" + }, + "peerDependencies": { + "@svgdotjs/svg.js": "^3.2.4", + "@svgdotjs/svg.select.js": "^4.0.1" + } + }, + "node_modules/@svgdotjs/svg.select.js": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.select.js/-/svg.select.js-4.0.2.tgz", + "integrity": "sha512-5gWdrvoQX3keo03SCmgaBbD+kFftq0F/f2bzCbNnpkkvW6tk4rl4MakORzFuNjvXPWwB4az9GwuvVxQVnjaK2g==", + "license": "MIT", + "engines": { + "node": ">= 14.18" + }, + "peerDependencies": { + "@svgdotjs/svg.js": "^3.2.4" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1259,12 +1320,30 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, + "node_modules/@types/http-proxy": { + "version": "1.17.16", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz", + "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/node": { + "version": "22.13.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", + "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, "node_modules/@types/prop-types": { "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", @@ -1314,6 +1393,12 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, + "node_modules/@yr/monotone-cubic-spline": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz", + "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==", + "license": "MIT" + }, "node_modules/acorn": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", @@ -1366,6 +1451,20 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/apexcharts": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-4.5.0.tgz", + "integrity": "sha512-E7ZkrVqPNBUWy/Rmg8DEIqHNBmElzICE/oxOX5Ekvs2ICQUOK/VkEkMH09JGJu+O/EA0NL31hxlmF+wrwrSLaQ==", + "license": "MIT", + "dependencies": { + "@svgdotjs/svg.draggable.js": "^3.0.4", + "@svgdotjs/svg.filter.js": "^3.0.8", + "@svgdotjs/svg.js": "^3.2.4", + "@svgdotjs/svg.resize.js": "^2.0.2", + "@svgdotjs/svg.select.js": "^4.0.1", + "@yr/monotone-cubic-spline": "^1.0.3" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1522,6 +1621,26 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1532,6 +1651,18 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browserslist": { "version": "4.24.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", @@ -1564,6 +1695,30 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -1794,7 +1949,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dev": true, "dependencies": { "ms": "^2.1.3" }, @@ -1879,6 +2033,12 @@ "integrity": "sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ==", "dev": true }, + "node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==", + "license": "MIT" + }, "node_modules/es-abstract": { "version": "1.23.9", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", @@ -2302,6 +2462,12 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2332,6 +2498,18 @@ "node": ">=16.0.0" } }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -2367,6 +2545,26 @@ "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "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", @@ -2437,6 +2635,12 @@ "node": ">=6.9.0" } }, + "node_modules/get-browser-rtc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-browser-rtc/-/get-browser-rtc-1.1.0.tgz", + "integrity": "sha512-MghbMJ61EJrRsDe7w1Bvqt3ZsBuqhce5nrn/XAwgwOXhcsz53/ltdxOse1h/8eKXj5slzxdsz56g5rzOFSGwfQ==", + "license": "MIT" + }, "node_modules/get-intrinsic": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", @@ -2630,6 +2834,57 @@ "node": ">= 0.4" } }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", + "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2664,6 +2919,12 @@ "node": ">=0.8.19" } }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -2808,7 +3069,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2850,7 +3110,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -2870,6 +3129,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-number-object": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", @@ -2886,6 +3154,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -3147,6 +3424,13 @@ "node": ">= 0.8.0" } }, + "node_modules/lib-jitsi-meet": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/lib-jitsi-meet/-/lib-jitsi-meet-1.0.6.tgz", + "integrity": "sha512-Hnp8F7btmIFBGh5hgli1uTzb7c7IgWBgTMFu4GnSasE8sx23RcTerXBjH+XZcsGsxnoW3pFKlU77za1a0o3qhw==", + "deprecated": "Deprecated. lib-jitsi-meet is not distributed via npm, use the source.", + "license": "Apache-2.0" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3197,6 +3481,19 @@ "node": ">= 0.4" } }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3212,8 +3509,7 @@ "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/nanoid": { "version": "3.3.8", @@ -3248,7 +3544,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3449,6 +3744,18 @@ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -3459,9 +3766,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "funding": [ { "type": "opencollective", @@ -3476,10 +3783,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -3503,7 +3811,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -3519,6 +3826,35 @@ "node": ">=6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -3530,6 +3866,19 @@ "node": ">=0.10.0" } }, + "node_modules/react-apexcharts": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.7.0.tgz", + "integrity": "sha512-03oScKJyNLRf0Oe+ihJxFZliBQM9vW3UWwomVn4YVRTN1jsIR58dLWt0v1sb8RwJVHDMbeHiKQueM0KGpn7nOA==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "apexcharts": ">=4.0.0", + "react": ">=0.13" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -3545,8 +3894,7 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-refresh": { "version": "0.14.2", @@ -3595,6 +3943,20 @@ "react-dom": ">=18" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -3637,6 +3999,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, "node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -3720,6 +4088,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safe-push-apply": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", @@ -3919,6 +4307,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-peer": { + "version": "9.11.1", + "resolved": "https://registry.npmjs.org/simple-peer/-/simple-peer-9.11.1.tgz", + "integrity": "sha512-D1SaWpOW8afq1CZGWB8xTfrT3FekjQmPValrqncJMX7QFl8YwhrPTZvMCANLtgBwwdS+7zURyqxDDEmY558tTw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "debug": "^4.3.2", + "err-code": "^3.0.1", + "get-browser-rtc": "^1.1.0", + "queue-microtask": "^1.2.3", + "randombytes": "^2.1.0", + "readable-stream": "^3.6.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -3927,6 +4344,15 @@ "node": ">=0.10.0" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.12", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", @@ -4033,16 +4459,17 @@ } }, "node_modules/styled-components": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.14.tgz", - "integrity": "sha512-KtfwhU5jw7UoxdM0g6XU9VZQFV4do+KrM8idiVCH5h4v49W+3p3yMe0icYwJgZQZepa5DbH04Qv8P0/RdcLcgg==", + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.15.tgz", + "integrity": "sha512-PpOTEztW87Ua2xbmLa7yssjNyUF9vE7wdldRfn1I2E6RTkqknkBYpj771OxM/xrvRGinLy2oysa7GOd7NcZZIA==", + "license": "MIT", "dependencies": { "@emotion/is-prop-valid": "1.2.2", "@emotion/unitless": "0.8.1", "@types/stylis": "4.2.5", "css-to-react-native": "3.2.0", "csstype": "3.1.3", - "postcss": "8.4.38", + "postcss": "8.4.49", "shallowequal": "1.1.0", "stylis": "4.3.2", "tslib": "2.6.2" @@ -4088,6 +4515,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -4202,6 +4641,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" + }, "node_modules/update-browserslist-db": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", @@ -4241,15 +4686,22 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, "node_modules/vite": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.7.tgz", - "integrity": "sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz", + "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.24.2", - "postcss": "^8.4.49", - "rollup": "^4.23.0" + "postcss": "^8.5.1", + "rollup": "^4.30.1" }, "bin": { "vite": "bin/vite.js" diff --git a/blip-project/package.json b/blip-project/package.json index f1e0a54..4e10067 100644 --- a/blip-project/package.json +++ b/blip-project/package.json @@ -3,6 +3,7 @@ "private": true, "version": "0.0.0", "type": "module", + "proxy": "https://192.168.1.42", "scripts": { "dev": "vite", "build": "vite build", @@ -10,10 +11,15 @@ "preview": "vite preview" }, "dependencies": { + "apexcharts": "^4.5.0", + "http-proxy-middleware": "^3.0.3", + "lib-jitsi-meet": "^1.0.6", "react": "^18.3.1", + "react-apexcharts": "^1.7.0", "react-dom": "^18.3.1", "react-router-dom": "^7.1.3", - "styled-components": "^6.1.14" + "simple-peer": "^9.11.1", + "styled-components": "^6.1.15" }, "devDependencies": { "@eslint/js": "^9.17.0", diff --git a/blip-project/src/Router.css b/blip-project/src/Router.css new file mode 100644 index 0000000..a160580 --- /dev/null +++ b/blip-project/src/Router.css @@ -0,0 +1,5 @@ +.mocDataImg { + width: 100%; + max-width: 80px; + aspect-ratio: 1 / 1; +} diff --git a/blip-project/src/Router.jsx b/blip-project/src/Router.jsx index 787abd6..15f7a0c 100644 --- a/blip-project/src/Router.jsx +++ b/blip-project/src/Router.jsx @@ -1,5 +1,198 @@ +import "./Router.css"; import { Route, Routes } from "react-router-dom"; +import Main from "./components/Page/Main/Main"; +import SidebarImg from "./svg/add.svg"; +import { + useRef, + useReducer, + createContext, + useCallback, + useMemo, + useState, +} from "react"; +import MyPageNoTeam from "./components/Page/MyPage/myPageNoTeam"; +import Profiles from "./components/Page/MyPage/Profiles/profile"; +import Profiles2 from "./components/Page/MyPage/Profiles/profile2"; +import MyPageTeam from "./components/Page/MyPage/myPageTeam"; + +const mocDateSide = [ + { + id: 0, + content: sidebar-img, + isPlus: true, + }, +]; + +function reducer(state, action) { + switch (action.type) { + case "CREATE": + return [action.data, ...state]; + case "Del": + return state.filter((item) => item.id != action.targetId); + case "Find": + return state.filter((item) => item.id === action.targetId); + case "Update": + return state.map((item) => + item.id === action.targetId ? { ...item, ...action.payload } : item + ); + default: + return state; + } +} + +export const SidebarContext = createContext(); +export const UseStateContext = createContext(); +export const DiscordContext = createContext(); +export const Call = createContext(); export const AppRouter = () => { - return ; + const [todos, dispatch] = useReducer(reducer, mocDateSide); + const idRefEven = useRef(2); + const idRefOdd = useRef(1); + + const onCreateone = useCallback((content) => { + const newId = idRefEven.current; + idRefEven.current += 2; + dispatch({ + type: "CREATE", + data: { + id: newId, + content: content, + isPlus: false, + }, + }); + }, []); + + const onCreatedouble = useCallback((content) => { + const newId = idRefOdd.current; + idRefOdd.current += 2; + dispatch({ + type: "CREATE", + data: { + id: newId, + content: content, + isPlus: false, + }, + }); + }, []); + + const onDel = useCallback((targetId) => { + dispatch({ + type: "Del", + targetId: targetId, + }); + }, []); + + const onFind = useCallback((targetId) => { + dispatch({ + type: "Find", + targetId: targetId, + }); + }, []); + + const memoizedDispatch = useMemo(() => { + return { + onCreateone, + onCreatedouble, + onDel, + onFind, + }; + }, []); + + const [setting, setSetting] = useState(false); + const [isAlarm, setIsAlarm] = useState(false); + const [isLetter, setIsLetter] = useState(false); + const [isFeedback, setIsFeedback] = useState(false); + const [isKeyword, setIsKeyword] = useState(false); + const [discord, setDiscord] = useState(false); + const [isMike, setIsMike] = useState(false); + const [isCamera, setIsCamera] = useState(false); + const [FullScreen, setFullScreen] = useState(false); + const [meetingEnd, setMeetingEnd] = useState(false); + const [isListening, setIsListening] = useState(false); + const [transcript, setTranscript] = useState(""); + const videoRef = useRef(null); + const [stream, setStream] = useState(null); + const [basic, setBasic] = useState(null); + const [TeamJoin, setTeamJoin] = useState(null); + const [targetId, setTargetId] = useState(null); + const [teamImages, setTeamImages] = useState({}); + + const [recorder, setRecorder] = useState(null); + const [recordedChunks, setRecordedChunks] = useState([]); + const [isUploading, setIsUploading] = useState(false); + + return ( + + + + + + } /> + } /> + } /> + } /> + + } /> + + + + + + ); }; diff --git a/blip-project/src/apis/instance.jsx b/blip-project/src/apis/instance.jsx new file mode 100644 index 0000000..e9138be --- /dev/null +++ b/blip-project/src/apis/instance.jsx @@ -0,0 +1,5 @@ +import axios from "axios"; + +export const instance = axios.create({ + baseURL: import.meta.env.VITE_USER_BASE_URL, +}); diff --git a/blip-project/src/components/CSS/AlarmTeam.css b/blip-project/src/components/CSS/AlarmTeam.css new file mode 100644 index 0000000..ea64263 --- /dev/null +++ b/blip-project/src/components/CSS/AlarmTeam.css @@ -0,0 +1,23 @@ +* { + margin: 0; + padding: 0; + overflow: hidden; +} + +.Alarm-p { + width: 85%; + border-radius: 15px; + border: 1px solid #cacaca; + display: flex; + align-items: center; + justify-content: center; +} + +.Alarm-p-font { + width: 85%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + diff --git a/blip-project/src/components/CSS/DateTeam.css b/blip-project/src/components/CSS/DateTeam.css new file mode 100644 index 0000000..a261281 --- /dev/null +++ b/blip-project/src/components/CSS/DateTeam.css @@ -0,0 +1,97 @@ +.DateTeamJoinNos { + height: 40%; + width: 100%; + border-radius: 12px; + border: 1px solid black; + padding: 10px 15px 20px; + box-sizing: border-box; /* 패딩을 포함한 크기 계산 */ +} + +.calendar-header { + display: flex; + justify-content: space-between; /* 년도/월과 달 넘기기 버튼을 양쪽으로 배치 */ + align-items: center; + margin-bottom: 10px; +} + +.year-month { + display: flex; + align-items: center; + gap: 5px; /* 년도와 월 사이의 간격 */ +} + +.year { + color: var(--gray-800); + margin: 0; /* 년도의 마진 제거 */ +} + +.month { + margin: 0; /* 월의 마진 제거 */ + color: var(--gray-800); +} + +.month-navigation { + display: flex; + align-items: center; + gap: 20px; /* 버튼 사이의 간격 */ +} + +.nav-button { + background: none; + border: none; + cursor: pointer; + font-size: 20px; + font-weight: 700; + color: var(--gray-800); +} + +.header-divider { + border-bottom: 1px solid #ccc; /* 헤더와 날짜를 구분하는 선 */ + margin-bottom: 10px; +} + +.calendar-grid { + display: grid; + grid-template-columns: repeat(7, 1fr); /* 7개의 열로 구성 */ + gap: 2px; /* 간격 줄임 */ + height: calc(100% - 60px); /* 헤더와 구분선을 제외한 높이 */ +} + +.calendar-day-header { + text-align: center; + padding: 5px; + border-radius: 4px; +} + +.calendar-week { + display: contents; /* 주 단위로 줄바꿈 */ +} + +.calendar-day { + text-align: center; + padding: 5px; + border-radius: 4px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; +} + +/* 같은 달이 아닌 날짜 스타일 */ +.calendar-day.other-month { + color: var(--gray-300); /* 회색으로 표시 */ +} + +/* 일요일 스타일 */ +.calendar-day.sunday { + color: var(--error-400); /* 빨간색으로 표시 */ +} + +.calendar-day:hover { + background-color: #e0e0e0; +} + +.calendar-day.selected { + border-radius: 80%; + background-color: var(--gray-100); /* 회색 배경 */ +} \ No newline at end of file diff --git a/blip-project/src/components/CSS/Discord.css b/blip-project/src/components/CSS/Discord.css new file mode 100644 index 0000000..07ad8df --- /dev/null +++ b/blip-project/src/components/CSS/Discord.css @@ -0,0 +1,76 @@ +* { + margin: 0; + padding: 0; + overflow: hidden; +} + +.discord { + width: 85%; + height: 100%; + display: flex; + flex-direction: column; +} + +.discord-end { + width: 100%; + height: 100%; +} + +.discord-end-x { + width: 95%; + height: 10%; + display: flex; + align-items: center; + justify-content: end; +} + +.discord-end-fnot { + width: 100%; + height: 80%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2%; +} + +.discord-body { + width: 100%; + height: 90%; + position: relative; + display: flex; + align-items: center; + justify-content: center; +} + +.discord-foot { + width: 100%; + height: 10%; + display: flex; + align-items: center; + justify-content: space-around; + gap: 50%; +} + +.discord-foot-Metting{ + width: 10%; + height: 100%; + display: flex; + gap: 30%; +} + +.discord-foot-Src { + width: 20%; + height: 80%; + display: flex; + align-items: center; + justify-content: space-around; +} + +.discord-foot-NoSrc { + width: 60%; + height: 100%; + display: flex; + align-items: center; + gap: 5%; +} diff --git a/blip-project/src/components/CSS/Feedback.css b/blip-project/src/components/CSS/Feedback.css new file mode 100644 index 0000000..5c07e8c --- /dev/null +++ b/blip-project/src/components/CSS/Feedback.css @@ -0,0 +1,21 @@ +.Feedback-container * { + margin: 0; + padding: 0; +} + +.Feedback-p { + width: 67%; + border-radius: 15px; + border: 1px solid #cacaca; + display: flex; + align-items: center; + justify-content: center; +} + +.Feedback-p-font { + width: 85%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/blip-project/src/components/CSS/FullScreen.css b/blip-project/src/components/CSS/FullScreen.css new file mode 100644 index 0000000..cb360a8 --- /dev/null +++ b/blip-project/src/components/CSS/FullScreen.css @@ -0,0 +1,53 @@ +* { + margin: 0; + padding: 0; + overflow: hidden; +} + +.FullScreen { + width: 100%; + height: 100vh; + display: flex; + flex-direction: column; + background-color: beige; +} + +.FullScreen-main { + width: 100%; + height: 90%; +} + +.FullScreen-foot { + width: 100%; + height: 10%; + display: flex; + align-items: center; + justify-content: space-around; + gap: 40%; +} + +.FullScreen-foot-Metting { + width: 10%; + height: 40%; + display: flex; + gap: 30%; +} + +.FullScreen-foot-src-main { + width: 30%; + height: 50%; + display: flex; + justify-content: space-between; +} + +.FullScreen-foot-src { + width: 50%; + display: flex; + align-items: center; + gap: 10%; +} + +.FullScreen-foot-exit { + display: flex; + align-items: center; +} diff --git a/blip-project/src/components/CSS/Grid.css b/blip-project/src/components/CSS/Grid.css new file mode 100644 index 0000000..26d8b4b --- /dev/null +++ b/blip-project/src/components/CSS/Grid.css @@ -0,0 +1,129 @@ + +.FullGrid-grid { + width: 95%; + height: 95%; + display: grid; + gap: 3%; + grid-template-columns: repeat(auto-fit, minmax(45%, 1fr)); + grid-auto-rows: 1fr; +} + +.screen { + background-color: blueviolet; + width: 100%; + height: 100%; + border-radius: 24px; + border: none; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + position: relative; +} + +.screen video { + position: absolute; + width: 100%; + height: 100%; + object-fit: cover; + transform: scaleX(-1); +} + +.FullGrid-main-circle { + width: 100%; + height: 60%; + display: flex; + align-items: end; + justify-content: center; +} + +.FullGrid-main-circle-src { + width: 20%; + aspect-ratio: 1/1; + border-radius: 50%; + background-color: black; +} + +.FullGrid-main-nofoot { + width: 100%; + display: flex; + align-items: center; + justify-content: center; + gap: 1%; + padding-left: 40%; +} + +.FullGrid-main-nofoot-video { + width: 100%; + height: 95%; + display: flex; + align-items: end; + justify-content: center; + gap: 1%; + z-index: 1000; + padding-left: 40%; +} + +.FullGrid-main-foot { + width: 100%; + height: 30%; +} + +.FullGrid-main-foot img { + display: block; + width: 10%; + height: 10%; +} + +.FullGrid-main-foot p { + display: flex; + flex-direction: column; + align-items: center; + color: #ffff; +} + +.FullGrid-main-last { + grid-column: span 2; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.FullGrid-main-last-Div { + background-color: blueviolet; + width: 50%; + height: 100%; + border-radius: 24px; + border: none; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + position: relative; +} + +.FullGrid-main-last video { + position: absolute; + width: 100%; + height: 100%; + display: flex; + object-fit: cover; + transform: scaleX(-1); +} + +.FullGrid-main-foot-last { + width: 100%; + height: 30%; + display: flex; + flex-direction: column; + align-items: center; +} + +.FullGrid-main-circle-src-last { + width: 20%; + aspect-ratio: 1/1; + border-radius: 50%; + background-color: black; +} \ No newline at end of file diff --git a/blip-project/src/components/TeamJoinNo/HeaderTeamJoinNo.css b/blip-project/src/components/CSS/HeaderTeam.css similarity index 78% rename from blip-project/src/components/TeamJoinNo/HeaderTeamJoinNo.css rename to blip-project/src/components/CSS/HeaderTeam.css index 56224ec..06ce1fc 100644 --- a/blip-project/src/components/TeamJoinNo/HeaderTeamJoinNo.css +++ b/blip-project/src/components/CSS/HeaderTeam.css @@ -1,11 +1,5 @@ - -*{ - margin: 0; - padding: 0; -} - .MHTeamJoinNo{ - width: 100%; + width: 1 00%; height: 64px; display: flex; justify-content: end; diff --git a/blip-project/src/components/CSS/Keyword.css b/blip-project/src/components/CSS/Keyword.css new file mode 100644 index 0000000..36dafce --- /dev/null +++ b/blip-project/src/components/CSS/Keyword.css @@ -0,0 +1,23 @@ +* { + margin: 0; + padding: 0; + overflow: hidden; +} + +.keyword-p { + width: 67%; + border-radius: 15px; + border: 1px solid #cacaca; + display: flex; + align-items: center; + justify-content: center; +} + +.keyword-p-font { + width: 85%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + diff --git a/blip-project/src/components/CSS/LetterTeam.css b/blip-project/src/components/CSS/LetterTeam.css new file mode 100644 index 0000000..145b7bd --- /dev/null +++ b/blip-project/src/components/CSS/LetterTeam.css @@ -0,0 +1,23 @@ +* { + margin: 0; + padding: 0; + overflow: hidden; +} + +.Letter-p { + width: 85%; + border-radius: 15px; + border: 1px solid #cacaca; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.Letter-p-font { + width: 85%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/blip-project/src/components/CSS/MainTeam.css b/blip-project/src/components/CSS/MainTeam.css new file mode 100644 index 0000000..3f6bf81 --- /dev/null +++ b/blip-project/src/components/CSS/MainTeam.css @@ -0,0 +1,53 @@ +* { + margin: 0; + padding: 0; + overflow: hidden; +} + +.Main-Team { + max-width: 100%; + height: 90vh; + display: flex; + gap: 20px; +} + +.Main-Team-Date { + width: 35%; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.Line { + border: 1px solid #cacaca; + border-radius: 12px; + width: 1290px; + height: 952px; + display: flex; + justify-content: center; + align-items: center; +} +.NoFeedBack { + position: absolute; + bottom: 100px; + width: 1146px; + height: 300px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + box-sizing: border-box; + white-space: nowrap; +} + +.FeedBackTitle { + margin-right: 1000px; +} + +.Feedback-p-font { + width: 100%; + display: flex; + align-items: center; + justify-content: center; + text-align: center; +} diff --git a/blip-project/src/components/TeamJoinNo/MainTeamJoinNo.css b/blip-project/src/components/CSS/MainTeamJoinNo.css similarity index 58% rename from blip-project/src/components/TeamJoinNo/MainTeamJoinNo.css rename to blip-project/src/components/CSS/MainTeamJoinNo.css index ca87f97..a088c02 100644 --- a/blip-project/src/components/TeamJoinNo/MainTeamJoinNo.css +++ b/blip-project/src/components/CSS/MainTeamJoinNo.css @@ -1,23 +1,19 @@ -* { +*{ margin: 0; padding: 0; + overflow: hidden; } -.MTJoinNoSrc{ +.MTJoinNoSrc { + max-width: 100%; height: 90vh; display: flex; gap: 20px; } -.MTJoinNoDate{ - width: 25%; +.MTJoinNoDate { + width: 35%; display: flex; flex-direction: column; justify-content: space-between; } - -.MTJoinNoMeeting{ - width: 100%; - height: 50%; - gap: 10px; -} \ No newline at end of file diff --git a/blip-project/src/components/CSS/MainTeamOwner.css b/blip-project/src/components/CSS/MainTeamOwner.css new file mode 100644 index 0000000..02ab7fd --- /dev/null +++ b/blip-project/src/components/CSS/MainTeamOwner.css @@ -0,0 +1,13 @@ +.Main-Team-owner { + max-width: 100%; + height: 90vh; + display: flex; + gap: 20px; +} + +.Main-Team-Date-owner { + width: 35%; + display: flex; + flex-direction: column; + justify-content: space-between; +} diff --git a/blip-project/src/components/CSS/MeetingContent.css b/blip-project/src/components/CSS/MeetingContent.css new file mode 100644 index 0000000..aaf0a83 --- /dev/null +++ b/blip-project/src/components/CSS/MeetingContent.css @@ -0,0 +1,14 @@ +.meeting-content { + width: 100%; + height: 80%; + display: flex; + justify-content: center; + +} + +.meeting-content-main { + display: flex; + align-items: center; + justify-content: center; + color: var(--gray-400); +} \ No newline at end of file diff --git a/blip-project/src/components/CSS/MeetingTeam.css b/blip-project/src/components/CSS/MeetingTeam.css new file mode 100644 index 0000000..fabc136 --- /dev/null +++ b/blip-project/src/components/CSS/MeetingTeam.css @@ -0,0 +1,18 @@ +.MeetingTeams { + width: 100%; + height: 38%; + border-radius: 12px; + color: var(--black); + background-color: var(--gray-50); +} + +.MeetingTFont { + padding: 10px; +} + +.MeetingTButton { + width: 100%; + height: 20%; + border-radius: 12px; + border: none; +} diff --git a/blip-project/src/components/CSS/Member.css b/blip-project/src/components/CSS/Member.css new file mode 100644 index 0000000..62fdd77 --- /dev/null +++ b/blip-project/src/components/CSS/Member.css @@ -0,0 +1,52 @@ +.member { + width: 15%; + height: 100%; + box-shadow: 0px 0px 1px 1px #dedede; + border: 1px solid #cacaca; +} + +.member-header { + width: 100%; + height: 12%; + border-bottom: 1px solid #cacaca; +} + +.member-header-TeamName-owner { + width: 100%; + height: 65%; + color: #ffff; + background-color: var(--main-400); + display: flex; + align-items: center; + justify-content: space-around; +} + +.member-header-member-owner{ + width: 100%; + height: 35%; + display: flex; + align-items: center; + justify-content: space-around; + gap: 20%; +} + +.member-header-TeamName { + width: 100%; + height: 65%; + color: #ffff; + background-color: var(--main-400); + display: flex; + align-items: center; + padding-left: 10px; +} + +.member-header-member { + width: 100%; + height: 35%; + padding-left: 10px; +} + +.member-name { + width: 100%; + height: 87%; +} diff --git a/blip-project/src/components/CSS/Modal.css b/blip-project/src/components/CSS/Modal.css new file mode 100644 index 0000000..10e2a8a --- /dev/null +++ b/blip-project/src/components/CSS/Modal.css @@ -0,0 +1,77 @@ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.25); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modal-content { + width: 65%; + height: 65%; + background-color: white; + border-radius: 24px; +} + +.modal-title { + padding: 40px; + display: flex; + justify-content: space-between; +} + +.modal-title-font-p { + color: var(--gray-600); +} + +.modal-team { + padding: 0px 45px; + width: 100%; + height:40%; + color: var(--gray-700); + display: flex; + flex-direction: column; + justify-content: space-around; +} + +.modal-team-buttons { + width: 90%; + height: 40%; + background-color: transparent; + display: flex; + align-items: start; + flex-direction: column; + justify-content: center; + border: none; + border-radius: 12px; +} + +.modal-button-main{ + width: 100%; + height: 25%; + display: flex; + justify-content: center; + align-items: end; +} + +.modal-button-400 { + width: 40%; + height: 30%; + background-color: var(--main-400 ); + color: white; + border-radius: 12px; + border: none; +} + +.modal-button-200 { + width: 40%; + height: 30%; + background-color: var(--main-200 ); + color: white; + border-radius: 12px; + border: none; +} diff --git a/blip-project/src/components/CSS/ModalCreate.css b/blip-project/src/components/CSS/ModalCreate.css new file mode 100644 index 0000000..3451498 --- /dev/null +++ b/blip-project/src/components/CSS/ModalCreate.css @@ -0,0 +1,67 @@ +.modal-create-header { + display: flex; + justify-content: space-between; + padding: 40px; +} + +.modal-create-p { + color: var(--gary-600); +} + +.modal-create-main { + width: 100%; + height: 25%; + padding-left: 50px; + display: flex; + flex-direction: column; + justify-content: space-around; +} + +.modal-create-main-title { + color: var(--gary-700); +} + +.modal-create-main p { + color: var(--gary-600); +} + +.modal-create-main input { + width: 40%; + height: 45%; + border-radius: 12px; + border: 1px solid #f2f2f2; + outline: none; + font-size: 100%; +} + +.modal-create-main input::placeholder { + font-size: 100%; + padding-left: 10px; + color: #cacaca; +} + +.modal-create-button { + width: 100%; + height: 45%; + display: flex; + justify-content: center; + align-items: end; +} + +.modal-create-button-400 { + width: 40%; + height: 17%; + background-color: var(--main-400); + color: white; + border-radius: 12px; + border: none; +} + +.modal-create-button-200 { + width: 40%; + height: 17%; + background-color: var(--main-200); + color: white; + border-radius: 12px; + border: none; +} \ No newline at end of file diff --git a/blip-project/src/components/CSS/ModalDel.css b/blip-project/src/components/CSS/ModalDel.css new file mode 100644 index 0000000..685ddfe --- /dev/null +++ b/blip-project/src/components/CSS/ModalDel.css @@ -0,0 +1,46 @@ +.modalDel-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.25); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modalDel-content { + width: 30%; + height: 30%; + background-color: white; + border-radius: 24px; + display: flex; + flex-direction: column; + justify-content: space-around; + gap: 20%; +} + +.modalDel-title { + display: flex; + justify-content: space-between; + padding: 3%; +} + +.modalDel-button-main { + width: 100%; + height: 20%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.modalDel-button { + width: 90%; + height: 100%; + color: white; + border-radius: 12px; + border: none; +} diff --git a/blip-project/src/components/CSS/ModalMeeting.css b/blip-project/src/components/CSS/ModalMeeting.css new file mode 100644 index 0000000..40a2962 --- /dev/null +++ b/blip-project/src/components/CSS/ModalMeeting.css @@ -0,0 +1,125 @@ +.modalMeeting-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.25); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modalMeeting-content { + width: 60%; + height: 70%; + background-color: white; + border-radius: 24px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.modalMeeting-title { + display: flex; + justify-content: space-between; + padding: 3% 3% 0 3%; +} + +.modalMeeting-body { + width: 100%; + height: 50%; + padding-left: 3%; + display: flex; + flex-direction: column; + gap: 10%; +} + +.modalMeeting-body-Topic { + width: 100%; + height: 35%; + display: flex; + flex-direction: column; + gap: 5%; +} + +.modalMeeting-body-Topic input { + width: 50%; + height: 40%; + border-radius: 12px; + border: 1px solid var(--gray-50); + padding-left: 1%; +} + +.modalMeeting-body-Topic input::placeholder { + color: var(--gray-200); +} + +.modalMeeting-body-setting { + width: 100%; + height: 25%; + display: flex; + flex-direction: column; + gap: 15%; +} + +.modalMeeting-body-setting-call { + display: flex; + color: var(--gray-600); +} + +.setting-call-mike { + width: 10%; + display: flex; + align-items: center; + gap: 15%; +} + +.setting-call-camera { + width: 10%; + display: flex; + align-items: center; + gap: 15%; +} + +.checkbox-label { + width: 10%; + height: 60%; + aspect-ratio: 1/1; + border: 2px solid var(--gray-600); +} + +.checkbox-label-checked { + width: 12%; + height: 75; + aspect-ratio: 1/1; +} + +.checkbox-label-checked::after { + width: 100%; + height: 100%; + content: "✔"; + font-size: 70%; + color: #ffff; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--Main-400); +} + +.modalMeeting-button-main { + width: 100%; + height: 20%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.modalMeeting-button { + width: 50%; + height: 50%; + border-radius: 12px; + border: none; +} diff --git a/blip-project/src/components/CSS/Modaljoin.css b/blip-project/src/components/CSS/Modaljoin.css new file mode 100644 index 0000000..c8906e3 --- /dev/null +++ b/blip-project/src/components/CSS/Modaljoin.css @@ -0,0 +1,67 @@ +.modal-Join-header { + display: flex; + justify-content: space-between; + padding: 40px; +} + +.modal-Join-p { + color: var(--gary-600); +} + +.modal-Join-main { + width: 100%; + height: 25%; + padding-left: 50px; + display: flex; + flex-direction: column; + justify-content: space-around; +} + +.modal-Join-main-title { + color: var(--gary-700); +} + +.modal-Join-main p { + color: var(--gary-600); +} + +.modal-Join-main input { + width: 40%; + height: 30%; + border-radius: 12px; + border: 1px solid #f2f2f2; + outline: none; +font-size: 100%; +} + +.modal-Join-main input::placeholder { + font-size: 100%; + padding-left: 10px; + color: #cacaca; +} + +.modal-Join-button { + width: 100%; + height: 45%; + display: flex; + justify-content: center; + align-items: end; +} + +.modal-Join-button-400 { + width: 40%; + height: 17%; + background-color: var(--main-400); + color: white; + border-radius: 12px; + border: none; +} + +.modal-Join-button-200 { + width: 40%; + height: 17%; + background-color: var(--main-200); + color: white; + border-radius: 12px; + border: none; +} \ No newline at end of file diff --git a/blip-project/src/components/CSS/OwnerTeam.css b/blip-project/src/components/CSS/OwnerTeam.css new file mode 100644 index 0000000..dec24c8 --- /dev/null +++ b/blip-project/src/components/CSS/OwnerTeam.css @@ -0,0 +1,69 @@ +.owner-main { + width: 85%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.owner-body { + width: 100%; + height: 60%; + display: flex; + flex-direction: column; + gap: 30px; + padding: 2%; +} + +.circle-main { + width: 20%; + height: 32%; + border-radius: 50%; + border:1px solid var(--gray-200) ; + display: flex; + align-items: center; + justify-content: center; +} + +.circle-main-img { + width: 80%; + height: 80%; + cursor: pointer; +} + +.circle-main input[type="file"] { + display: none; +} + +.TeamName-input{ + width: 100%; + height: 10%; +} + +.TeamName-input input{ + width: 50%; + height: 100%; + border: 1px solid var(--gray-50); + border-radius: 12px; + padding-left: 2%; +} + +.TeamName-input input::placeholder{ + font-size: 100%; +} + +.owner-button { + height: 20%; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 2%; +} + +.owner-button button { + width: 25%; + height: 35%; + color: #ffff; + border-radius: 12px; + border: none; +} diff --git a/blip-project/src/components/CSS/StartTeam.css b/blip-project/src/components/CSS/StartTeam.css new file mode 100644 index 0000000..506a623 --- /dev/null +++ b/blip-project/src/components/CSS/StartTeam.css @@ -0,0 +1,108 @@ +.start-main { + width: 67%; + border-radius: 15px; + border: 1px solid #cacaca; + display: flex; + justify-content: end; +} + +.council { + width: 85%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; +} + +.council-keyword { + width: 90%; + height: 32%; + border-radius: 12px; + background-image: url("/src/svg/council.svg"); + display: flex; + flex-direction: column; + justify-content: end; +} + +.council-keyword-main { + width: 50%; + height: 35%; + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 20px; +} + +.council-keyword-main button { + width: 22%; + height: 35%; + color: #ffff; + background-color: var(--main-400); + border: none; + border-radius: 60px; +} + +.council-feedback { + width: 90%; + height: 20%; + border-radius: 12px; + border: 1px solid var(--gray-200); + display: flex; + justify-content: space-between; + align-items: center; +} + +.council-feedback-main { + width: auto; + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-around; + padding-left: 20px; +} + +.council-feedback-main button { + width: 45%; + height: 20%; + color: #ffff; + background-color: var(--main-400); + border: none; + border-radius: 60px; +} + +.council-feedback img { + height: 100%; +} + +.council-graph { + width: 90%; + height: 38%; + border-radius: 12px; + border: 1px solid var(--gray-200); + display: flex; + justify-content: space-between; +} + +.council-graph-main { + width: 70%; + height: 100%; +} + +.council-graph-font { + padding: 15px; +} + +.council-graph-graph { + width: 50%; + height: 70%; + display: flex; + align-items: center; + justify-self: center; +} + +.council-graph img { + width: 29%; + height: 100%; + object-fit: cover; +} diff --git a/blip-project/src/components/TeamJoinNo/StartTeamJoinNo.css b/blip-project/src/components/CSS/StartTeamJoinNo.css similarity index 91% rename from blip-project/src/components/TeamJoinNo/StartTeamJoinNo.css rename to blip-project/src/components/CSS/StartTeamJoinNo.css index 17048a5..d80fbf9 100644 --- a/blip-project/src/components/TeamJoinNo/StartTeamJoinNo.css +++ b/blip-project/src/components/CSS/StartTeamJoinNo.css @@ -1,5 +1,5 @@ .StartTeamJoinNos { - width: 67%; + width: 85%; border-radius: 15px; border: 1px solid #cacaca; display: flex; @@ -35,13 +35,13 @@ .STJoinNoInput { width: 45%; height: 20%; + padding-left: 10px; border-radius: 12px; - border: 1px solid var(--gray-200); outline: none; } input::placeholder{ - padding-left: 20px; + opacity: 1; } diff --git a/blip-project/src/components/CSS/UserStart.css b/blip-project/src/components/CSS/UserStart.css new file mode 100644 index 0000000..302e011 --- /dev/null +++ b/blip-project/src/components/CSS/UserStart.css @@ -0,0 +1,100 @@ +.council { + width: 85%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; +} + +.council-keyword { + width: 90%; + height: 32%; + border-radius: 12px; + background-image: url("/src/svg/council.svg"); + display: flex; + flex-direction: column; + justify-content: end; +} + +.council-keyword-main { + width: 50%; + height: 35%; + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 20px; +} + +.council-keyword-main button { + width: 22%; + height: 35%; + color: #ffff; + background-color: var(--main-400); + border: none; + border-radius: 60px; +} + +.council-feedback { + width: 90%; + height: 20%; + border-radius: 12px; + border: 1px solid var(--gray-200); + display: flex; + justify-content: space-between; + align-items: center; +} + +.council-feedback-main { + width: auto; + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-around; + padding-left: 20px; +} + +.council-feedback-main button { + width: 45%; + height: 20%; + color: #ffff; + background-color: var(--main-400); + border: none; + border-radius: 60px; +} + +.council-feedback img { + height: 100%; +} + +.council-graph { + width: 90%; + height: 38%; + border-radius: 12px; + border: 1px solid var(--gray-200); + display: flex; + justify-content: space-between; +} + +.council-graph-main { + width: 70%; + height: 100%; +} + +.council-graph-font { + padding: 15px; +} + +.council-graph-graph { + width: 50%; + height: 70%; + display: flex; + align-items: center; + justify-self: center; +} + +.council-graph img { + width: 29%; + height: 100%; + object-fit: cover; +} diff --git a/blip-project/src/components/CSS/myPage.css b/blip-project/src/components/CSS/myPage.css new file mode 100644 index 0000000..0c649f3 --- /dev/null +++ b/blip-project/src/components/CSS/myPage.css @@ -0,0 +1,4 @@ +.STJoinNoLink, +.STJoinNoButton { + display: none !important; +} diff --git a/blip-project/src/components/CSS/sidebarTeam.css b/blip-project/src/components/CSS/sidebarTeam.css new file mode 100644 index 0000000..bc087a8 --- /dev/null +++ b/blip-project/src/components/CSS/sidebarTeam.css @@ -0,0 +1,48 @@ +.MainSTJoinNo { + height: 100%; + width: 6%; + margin-top: 0.5%; + padding-top: 0.5%; + padding-right: 10px; + padding-left: 20px; + gap: 2%; + overflow-y: scroll; +} + +.MainSTJoinNo::-webkit-scrollbar { + width: 1px; + overflow: hidden; +} + +.content-item { + margin-bottom: 20%; + max-width: 90%; + min-height: 2%; + aspect-ratio: 1 / 1; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 0 3px 3px #31ad5f; +} + +.content-item-plus { + width: 90%; + display: flex; + justify-content: center; + aspect-ratio: 1/1; + box-shadow: none; + border: none; + border-radius: 12px; + margin-bottom: 20%; +} + +.content-item-image { + margin-bottom: 20%; + width: 90%; + aspect-ratio: 1 / 1; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/blip-project/src/components/Modal/ModalDel.jsx b/blip-project/src/components/Modal/ModalDel.jsx new file mode 100644 index 0000000..6dde617 --- /dev/null +++ b/blip-project/src/components/Modal/ModalDel.jsx @@ -0,0 +1,46 @@ +import "../CSS/ModalDel.css"; +import { typography } from "../../../fonts/fonts"; +import { color } from "../../../style/color"; +import ESC from "../../../svg/ESC.svg"; +import { useContext } from "react"; +import { SidebarContext } from "../../../Router"; +import { TeamDel } from "../Main/MainTeamOwner"; +// import { TeamDel } from "../Page/Main/Main"; +import { useNavigate } from "react-router-dom"; + +const ModalDel = ({ onClose }) => { + const { dispatch } = useContext(SidebarContext); + const { itemId } = useContext(TeamDel); + const nav = useNavigate(); + + const ClickDel = () => { + if (itemId) { + dispatch.onDel(itemId); + nav("/", { state: {} }); + } + }; + + return ( +
+
+
+

+ 정말 스페이스를 삭제 하실건가요? +

+ +
+
+ +
+
+
+ ); +}; + +export default ModalDel; diff --git a/blip-project/src/components/Modal/ModalMeeting.jsx b/blip-project/src/components/Modal/ModalMeeting.jsx new file mode 100644 index 0000000..f1ae4ec --- /dev/null +++ b/blip-project/src/components/Modal/ModalMeeting.jsx @@ -0,0 +1,181 @@ +import "../../CSS/ModalMeeting.css"; +import { typography } from "../../../fonts/fonts"; +import { color } from "../../../style/color"; +import { useState, useContext } from "react"; +import ESC from "../../../svg/ESC.svg"; +import { UseStateContext } from "../../../Router"; +import { TeamDel } from "../Main/MainTeamOwner"; +// import { TeamDel } from "../Page/Main/Main"; + +const ModalMeeting = ({ onClose }) => { + const [isTopic, setIsTopic] = useState(""); + const [isCheckMike, setIsCheckMike] = useState(false); + const [isCheckCamera, setIsCheckCamera] = useState(false); + const { + setIsMike, + setIsCamera, + setting, + setSetting, + isAlarm, + setIsAlarm, + isLetter, + setIsLetter, + isFeedback, + setIsFeedback, + isKeyword, + setIsKeyword, + discord, + setDiscord, + } = useContext(UseStateContext); + + + const { itemId } = useContext(TeamDel); + + const onClickDiscord = () => { + console.log("key={itemId}", itemId); + if (!discord) { + setDiscord((preState) => !preState); + onClose(); + if (isLetter === true) { + setIsLetter((preState) => !preState); + } else if (isAlarm) { + setIsAlarm((preState) => !preState); + } else if (setting === true) { + setSetting((preState) => !preState); + } else if (isFeedback === true) { + setIsFeedback((preState) => !preState); + } else if (isKeyword === true) { + setIsKeyword((preState) => !preState); + } + } + }; + + const onChageTopic = (e) => { + setIsTopic(e.target.value); + console.log(e.target.value); + }; + + const onChnageCheckMike = () => { + setIsCheckMike(!isCheckMike); + setIsMike((prev) => !prev); + }; + const onChnageCheckCamera = () => { + setIsCheckCamera(!isCheckCamera); + setIsCamera((prev) => !prev); + }; + + return ( +
+
+
+
+

회의 시작하기

+

+ BLIP은 실시간 요약, 키워드 기록, 참여율 분석으로 더 스마트하고 + 효율적인 회의를 제공합니다. +

+
+ +
+
+
+
+ 회의 주제 +
+

+ 회의 주제를 정해주세요! +

+ +
+
+
+
+ 설정 +
+

+ 무엇을 허용하고 입장하실건가요? +

+
+
+
+

마이크

+ +
+
+

카메라

+ +
+
+
+
+
+ {isTopic || isCheckMike || isCheckCamera ? ( + + ) : ( + + )} +
+
+
+ ); +}; + +export default ModalMeeting; diff --git a/blip-project/src/components/Page/Main/FullScreen.jsx b/blip-project/src/components/Page/Main/FullScreen.jsx new file mode 100644 index 0000000..4261d13 --- /dev/null +++ b/blip-project/src/components/Page/Main/FullScreen.jsx @@ -0,0 +1,133 @@ +import "../../CSS/FullScreen.css"; +import { color } from "../../../style/color"; +import { useContext, useState } from "react"; +import { TeamDel } from "./Main"; +import { UseStateContext } from "../../../Router"; +import { DiscordContext } from "../../../Router"; +import ModalStart from "../Modal/ModalStart"; +import ModalStop from "../Modal/ModalStop"; +import Exit from "../../../svg/Exit.svg"; +import XFullScreen from "../../../svg/XFullScreen.svg"; +import DisAlarm from "../../../svg/DisAlarm.svg"; +import NoMike from "../../../svg/NoMike.svg"; +import NoCamera from "../../../svg/NoCamera.svg"; +import Mike from "../../../svg/Mike.svg"; +import Camera from "../../../svg/DisCamera.svg"; +import MettingStart from "../../../svg/MettingStart.svg"; +import MettingStop from "../../../svg/MettingStop.svg"; +/* import Grid from "../Src/function/Grid"; */ + +const FullScreenPage = () => { + const { itemId } = useContext(TeamDel); + + const { + isMike, + setIsMike, + isCamera, + setIsCamera, + FullScreen, + setFullScreen, + meetingEnd, + setMeetingEnd, + } = useContext(UseStateContext); + + const { setIsListening } = useContext(DiscordContext); + + const [peopleCount, setPeopleCount] = useState(0); + + const gridStyle = { + display: "grid", + placeItems: "center", + gridTemplateColumns: `repeat(${peopleCount}, 1fr)`, + gap: "10px", + }; + + const onClickFull = () => { + if (FullScreen) setFullScreen((preState) => !preState); + }; + + const onClickMike = () => { + console.log("ddd", isCamera); + console.log("sss", isMike); + if (!isCamera) { + setIsMike((preState) => !preState); + } + setIsListening((preState) => !preState); + }; + + const onClickCamera = () => { + setIsCamera((preState) => !preState); + if (!isMike) { + setIsMike((preState) => !preState); + } + }; + + const onClickMeetingEnd = () => { + if (!meetingEnd) { + setMeetingEnd((preState) => !preState); + setFullScreen((preState) => !preState); + } + }; + + const [isModalOpen, setIsModalOpen] = useState(false); + const [isModalStart, setIsModalStart] = useState(false); + const [isMettingStop, setIsMettingStop] = useState(false); + + const openModalStop = () => setIsModalOpen(true); + const closeModal = () => setIsModalOpen(false); + + const openModalStart = () => setIsModalStart(true); + const IsCloseModal = () => setIsModalStart(false); + + return ( +
+
+ +
+
+ {itemId % 2 === 0 ? ( + <> +
+ + +
+ + ) : ( + "" + )} +
+
+ + + +
+
+ +
+
+
+ {isModalStart && ( + + )} + {isModalOpen && ( + + )} +
+ ); +}; + +export default FullScreenPage; diff --git a/blip-project/src/components/Page/Main/Main.jsx b/blip-project/src/components/Page/Main/Main.jsx new file mode 100644 index 0000000..71a4fec --- /dev/null +++ b/blip-project/src/components/Page/Main/Main.jsx @@ -0,0 +1,86 @@ +import MainTeam from "./MainTeam"; +import MainTeamOwner from "./MainTeamOwner"; +import MTeamJoinNo from "./MainTeamJoinNo"; +import FullScreenPage from "./FullScreen"; +import { useLocation } from "react-router-dom"; +import { SidebarContext } from "../../../Router"; +import { UseStateContext } from "../../../Router"; +import { createContext, useState, useContext, useEffect } from "react"; + +export const TeamDel = createContext(); +export const FindId = createContext({ + filteredItem: null, + targetId: null, + setTargetId: () => {}, +}); + +const Main = () => { + const location = useLocation(); + const { itemContent, itemId, itemImage, TeamId } = location.state || {}; + const { todos } = useContext(SidebarContext); + const [filteredItem, setFilteredItem] = useState(null); + const { FullScreen, targetId, setTargetId } = useContext(UseStateContext); + const [Owner, setOwner] = useState(null); + const [join, setJoin] = useState(null); + const [image, setImage] = useState(null); + const [teamImages, setTeamImages] = useState({}); + + useEffect(() => { + const matchingId = todos.find((item) => item.id === itemId); + setFilteredItem(matchingId); + }, [todos, itemId]); + + useEffect(() => { + if (targetId === null) { + const foodId = todos.find((item) => item.id === itemId)?.id || null; + setTargetId(foodId); + console.log(targetId); + } + }, [targetId, itemId, todos, setTargetId]); + + return ( + <> + + + {FullScreen ? ( + + ) : ( + <> + {Owner ? ( + + ) : join ? ( + + ) : ( + + )} + + )} + + + + ); +}; + +export default Main; diff --git a/blip-project/src/components/Page/Main/MainTeam.jsx b/blip-project/src/components/Page/Main/MainTeam.jsx new file mode 100644 index 0000000..9d2a81d --- /dev/null +++ b/blip-project/src/components/Page/Main/MainTeam.jsx @@ -0,0 +1,24 @@ +import "../../CSS/MainTeam.css"; +import DateTeam from "../Src/DateTeam"; +import HeaderTeam from "../Src/page/HeaderTeam"; +import SidebarTeam from "../Src/sidebarTeam"; +import StartTeam from "./StartTeam"; +import MeetingTeam from "../Src/MeetingTeam"; + +const MainTeam = () => { + return ( + <> + +
+ + +
+ + +
+
+ + ); +}; + +export default MainTeam; diff --git a/blip-project/src/components/Page/Main/MainTeamJoinNo.jsx b/blip-project/src/components/Page/Main/MainTeamJoinNo.jsx new file mode 100644 index 0000000..ca67f56 --- /dev/null +++ b/blip-project/src/components/Page/Main/MainTeamJoinNo.jsx @@ -0,0 +1,24 @@ +import "../../CSS/MainTeamJoinNo.css"; +import DateTeam from "../Src/DateTeam"; +import HeaderTeam from "../Src/page/HeaderTeam"; +import SidebarTeam from "../Src/sidebarTeam"; +import StartTeam from "./StartTeam"; +import MeetingTeam from "../Src/MeetingTeam"; + +const MTeamJoinNo = () => { + return ( + <> + +
+ + +
+ + +
+
+ + ); +}; + +export default MTeamJoinNo; diff --git a/blip-project/src/components/Page/Main/MainTeamOwner.jsx b/blip-project/src/components/Page/Main/MainTeamOwner.jsx new file mode 100644 index 0000000..7d1d420 --- /dev/null +++ b/blip-project/src/components/Page/Main/MainTeamOwner.jsx @@ -0,0 +1,24 @@ +import "../../CSS/MainTeamOwner.css"; +import DateTeamJoinNo from "../Src/DateTeam"; +import HeaderTeam from "../Src/page/HeaderTeam"; +import SidebarTeam from "../Src/sidebarTeam"; +import StartTeam from "./StartTeam"; +import MeetingTeam from "../Src/MeetingTeam"; + +const MainTeamOwner = () => { + return ( + <> + +
+ + +
+ + +
+
+ + ); +}; + +export default MainTeamOwner; diff --git a/blip-project/src/components/Page/Main/StartTeam.jsx b/blip-project/src/components/Page/Main/StartTeam.jsx new file mode 100644 index 0000000..f3ff8d4 --- /dev/null +++ b/blip-project/src/components/Page/Main/StartTeam.jsx @@ -0,0 +1,39 @@ +import "../../CSS/StartTeam.css"; +import Member from "../Src/Member"; +import UserStart from "../Src/page/UserStart"; +import OwnerTeam from "../Src/page/OwnerTeam"; +import { useContext } from "react"; +import { UseStateContext } from "../../../Router"; +import Alarm from "../Src/page/AlarmTeam"; +import Letter from "../Src/page/LetterTeam"; +import Discord from "../Src/page/Discord"; +import StartTeamJoinNo from "../Src/page/StartTeamJoinNo"; +import MainJoin from "./MainTeam"; + +const StartTeam = () => { + const { setting, isAlarm, isLetter, discord, basic, join } = + useContext(UseStateContext); + + return ( +
+ + {setting ? ( + + ) : isAlarm ? ( + + ) : isLetter ? ( + + ) : discord ? ( + + ) : basic ? ( + + ) : join ? ( + + ) : ( + + )} +
+ ); +}; + +export default StartTeam; diff --git a/blip-project/src/components/Page/Modal/Modal.jsx b/blip-project/src/components/Page/Modal/Modal.jsx new file mode 100644 index 0000000..3e632f9 --- /dev/null +++ b/blip-project/src/components/Page/Modal/Modal.jsx @@ -0,0 +1,133 @@ +import "../../CSS/Modal.css" +import { typography } from "../../../fonts/fonts"; +import { color } from "../../../style/color"; +import ESC from "../../../svg/ESC.svg" +import { useState } from "react"; +import ModalCreate from "./ModalCreate"; +import ModalJoin from "./ModalJoin"; + +const Modal = ({ onClose }) => { + const [isColor, setIsColor] = useState(false); + const [isColorButton, setIsColorButton] = useState(false); + const [isModalJoin, setIsModalJoin] = useState(false); + const [isModalCreate, setIsModalCreate] = useState(false); + + const OpenModalJoin = () => setIsModalJoin(true); + const CloseModalJoin = () => setIsModalJoin(false); + + const OpenModalCreate = () => setIsModalCreate(true); + const CloseModalCreate = () => setIsModalCreate(false); + + const clickisColor = () => { + setIsColor(true); + setIsColorButton(false); + if (isColor === true) { + setIsColor(false); + } + }; + + const clickisColorButton = () => { + setIsColor(false); + setIsColorButton(true); + if (isColorButton === true) { + setIsColorButton(false); + } + }; + + return ( +
+
+
+
+

무엇을 하실건가요?

+

+ BLIP은 실시간 요약, 키워드 기록, 참여율 분석으로 더 스마트하고 + 효율적인 회의를 제공합니다. +

+
+
+ +
+
+
+ {isColor ? ( + + ) : ( + + )} + {isColorButton ? ( + + ) : ( + + )} +
+
+ {isColor ? ( + + ) : isColorButton ? ( + + ) : ( + + )} +
+
+ {isModalJoin && } + {isModalCreate && } +
+ ); +}; + +export default Modal; diff --git a/blip-project/src/components/Page/Modal/ModalCreate.jsx b/blip-project/src/components/Page/Modal/ModalCreate.jsx new file mode 100644 index 0000000..d20e172 --- /dev/null +++ b/blip-project/src/components/Page/Modal/ModalCreate.jsx @@ -0,0 +1,134 @@ +import "../../CSS/ModalCreate.css"; +import { typography } from "../../../fonts/fonts"; +import { color } from "../../../style/color"; +import ESC from "../../../svg/ESC.svg"; +import { useState, useContext, useRef, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { SidebarContext } from "../../../Router"; +import { TeamDel } from "../Main/Main"; +import axios from "axios"; + +const ModalCreate = ({ onClose }) => { + const { dispatch } = useContext(SidebarContext); + const { setOwner, setJoin, join } = useContext(TeamDel); + const [content, setContent] = useState(""); + const [isLoading, setIsLoading] = useState(false); + const [data, setData] = useState(false); + const submitRef = useRef(); + const nav = useNavigate(); + + const onChangeInput = (e) => { + setContent(e.target.value); + console.log(e.target.value); + }; + + const onKeyDownCreate = (e) => { + if (e.key === "Enter") { + handleSubmit(); + } + }; + + const apiUrl = import.meta.env.VITE_API_URL_URL_CREATE; + + console.log(apiUrl, "afdnmhtrhmjy"); + + const handleSubmit = async () => { + const url = `${apiUrl}/data`; + const accessToken = "토큰 값"; + + if (content === "") { + submitRef.current.focus(); + return; + } + + const data = { + team_name: content, + nick_name: "er", + }; + + try { + const response = await axios.post(url, data, { + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + }); + console.log("팀 생성 성공:", response.data); + + setOwner((prev) => !prev); + if (join) { + setJoin((prev) => !prev); + } + + const TeamId = response.data.team_id; + nav("/", { state: { content, TeamId } }); + console.log(TeamId); + dispatch.onCreateone(content); + setContent(""); + onClose(); + } catch (error) { + console.error("팀 생성 실패:", error); + } finally { + setIsLoading(false); + } + }; + + return ( +
+
+
+
+
팀스페이스 만들기
+
+ BLIP은 실시간 요약, 키워드 기록, 참여율 분석으로 더 스마트하고 + 효율적인 회의를 제공합니다. +
+
+ 닫기 +
+
+
+ 팀스페이스 +
+

+ 팀스페이스의 이름을 정해주세요! +

+ +
+
+ {content ? ( + + ) : ( + + )} +
+
+
+ ); +}; + +export default ModalCreate; diff --git a/blip-project/src/components/Page/Modal/ModalDel.jsx b/blip-project/src/components/Page/Modal/ModalDel.jsx new file mode 100644 index 0000000..ef48866 --- /dev/null +++ b/blip-project/src/components/Page/Modal/ModalDel.jsx @@ -0,0 +1,54 @@ +import "../../CSS/ModalDel.css"; +import { typography } from "../../../fonts/fonts"; +import { color } from "../../../style/color"; +import ESC from "../../../svg/ESC.svg"; +import { useContext } from "react"; +import { SidebarContext } from "../../../Router"; +import { TeamDel } from "../Main/Main"; +import { UseStateContext } from "../../../Router"; +import { useNavigate } from "react-router-dom"; + +const ModalDel = ({ onClose }) => { + const { dispatch } = useContext(SidebarContext); + const { itemId, setOwner, setJoin } = useContext(TeamDel); + const { setSetting, setBasic } = useContext(UseStateContext); + const nav = useNavigate(); + + const ClickDel = () => { + if (itemId) { + dispatch.onDel(itemId); + nav("/", { state: {} }); + onClose(); + setOwner(false); + setJoin(false); + setSetting(false); + setBasic(false); + } else { + console.error("No item selected for deletion"); + } + }; + + return ( +
+
+
+

+ 정말 스페이스를 삭제 하실건가요? +

+ 스페이스 삭제 창 닫기 +
+
+ +
+
+
+ ); +}; + +export default ModalDel; diff --git a/blip-project/src/components/Page/Modal/ModalJoin.jsx b/blip-project/src/components/Page/Modal/ModalJoin.jsx new file mode 100644 index 0000000..fde1ff7 --- /dev/null +++ b/blip-project/src/components/Page/Modal/ModalJoin.jsx @@ -0,0 +1,153 @@ +import "../../CSS/ModalJoin.css"; +import { typography } from "../../../fonts/fonts"; +import { color } from "../../../style/color"; +import ESC from "../../../svg/ESC.svg"; +import { useState, useContext, useRef } from "react"; +import { useNavigate } from "react-router-dom"; +import { SidebarContext } from "../../../Router"; +import { TeamDel } from "../Main/Main"; +import { FindId } from "../Main/Main"; +import axios from "axios"; + +const ModalJoin = ({ onClose }) => { + const [isInput, setIsInput] = useState(""); + const [isValidURL, setIsValidURL] = useState(true); // URL 유효성 상태 + const { onCreatedouble, dispatch } = useContext(SidebarContext); + const { setOwner, setJoin, Owner, TeamJoin, setTeamJoin } = + useContext(TeamDel); + const { TeamId } = useContext(FindId); + const [content, setContent] = useState(""); + const [data, setData] = useState(false); + const submitRef = useRef(); + + const onChangeInput = (e) => { + const value = e.target.value; + setIsInput(value); + + // URL 유효성 검사 + try { + new URL(value); // URL 객체로 변환 + setIsValidURL(true); // 유효한 URL + } catch (error) { + setIsValidURL(false); // 유효하지 않은 URL + } + }; + + const nav = useNavigate(); + + const apiUrl = import.meta.env.VITE_API_URL_URL_JOIN; + + const joinTeam = async (TeamId) => { + const url = `${apiUrl}/data`; + const accessToken = "토큰 값"; + + const data = { + team_id: "ertyui", + }; + try { + const response = await axios.post(url, data, { + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + }); + console.log("팀 가입 성공", response.data); + return response.data; + } catch (error) { + console.log("팀 가입 실패", error); + alert("팀 참가에 실패했습니다. 다시 시도해주세요."); + } + }; + + const onClickUrl = async () => { + if (isValidURL) { + const teamId = new URL(isInput).searchParams.get("team_id"); + + if (teamId) { + const result = await joinTeam(teamId); + + if (result) { + nav("/", { state: { isInput } }); + dispatch.onCreatedouble(content); + setContent(""); + setJoin((prev) => !prev); + if (Owner) { + setOwner((prev) => !prev); + } + } + } else { + alert("유효하지 않은 초대 링크입니다. 다시 확인해주세요."); + } + } else if (content === "") { + submitRef.current.focus(); + return; + } + }; + + const onKeyDownUrl = (e) => { + if (e.key === "Enter") { + onClickUrl(); + } + }; + + return ( +
+
+
+
+
팀스페이스 입장하기
+
+ 팀을 찾고 목표를 이루세요! +
+
+ 닫기 +
+
+
+ 초대링크 +
+

+ 초대 받은 링크를 입력해주세요! +

+ +
+
+ +
+
+
+ ); +}; + +export default ModalJoin; diff --git a/blip-project/src/components/Page/Modal/ModalMeeting.jsx b/blip-project/src/components/Page/Modal/ModalMeeting.jsx new file mode 100644 index 0000000..0a2fc8e --- /dev/null +++ b/blip-project/src/components/Page/Modal/ModalMeeting.jsx @@ -0,0 +1,191 @@ +import "../../CSS/ModalMeeting.css"; +import { typography } from "../../../fonts/fonts"; +import { color } from "../../../style/color"; +import { useState, useContext, useEffect } from "react"; +import ESC from "../../../svg/ESC.svg"; +import { UseStateContext } from "../../../Router"; +import { TeamDel } from "../Main/Main"; + +const ModalMeeting = ({ onClose }) => { + const [isTopic, setIsTopic] = useState(""); + const [isCheckMike, setIsCheckMike] = useState(false); + const [isCheckCamera, setIsCheckCamera] = useState(false); + + const { + setIsMike, + setIsCamera, + setting, + setSetting, + isAlarm, + setIsAlarm, + isLetter, + setIsLetter, + isFeedback, + setIsFeedback, + isKeyword, + setIsKeyword, + discord, + setDiscord, + basic, + setBasic, + } = useContext(UseStateContext); + + const { itemId, Owner, setOwner, join, setJoin } = useContext(TeamDel); + + const onClickDiscord = () => { + console.log("key={itemId}", itemId); + setDiscord((perState) => !perState); + console.log("시발시발", discord); + onClose(); + if (isLetter) { + setIsLetter((preState) => !preState); + } else if (isAlarm) { + setIsAlarm((preState) => !preState); + } else if (setting) { + setSetting((preState) => !preState); + } else if (isFeedback) { + setIsFeedback((preState) => !preState); + } else if (isKeyword) { + setIsKeyword((preState) => !preState); + } else if (Owner) { + setOwner((perState) => !perState); + } else if (join) { + setJoin((perState) => !perState); + } else if (basic) { + setBasic((perState) => !perState); + } + }; + + useEffect(() => { + console.log("discord 상태 변경:", discord); + }, [discord]); + + const onChageTopic = (e) => { + setIsTopic(e.target.value); + console.log(e.target.value); + }; + + const onChnageCheckMike = () => { + setIsCheckMike(!isCheckMike); + setIsMike((prev) => !prev); + }; + const onChnageCheckCamera = () => { + setIsCheckCamera(!isCheckCamera); + setIsCamera((prev) => !prev); + }; + + return ( +
+
+
+
+

회의 시작하기

+

+ BLIP은 실시간 요약, 키워드 기록, 참여율 분석으로 더 스마트하고 + 효율적인 회의를 제공합니다. +

+
+ +
+
+
+
+ 회의 주제 +
+

+ 회의 주제를 정해주세요! +

+ +
+
+
+
+ 설정 +
+

+ 무엇을 허용하고 입장하실건가요? +

+
+
+
+

마이크

+ +
+
+

카메라

+ +
+
+
+
+
+ {isTopic || isCheckMike || isCheckCamera ? ( + + ) : ( + + )} +
+
+
+ ); +}; + +export default ModalMeeting; diff --git a/blip-project/src/components/Page/Modal/ModalStart.jsx b/blip-project/src/components/Page/Modal/ModalStart.jsx new file mode 100644 index 0000000..81a3881 --- /dev/null +++ b/blip-project/src/components/Page/Modal/ModalStart.jsx @@ -0,0 +1,83 @@ +import styled from "styled-components"; +import { typography } from "../../../fonts/fonts"; +import { color } from "../../../style/color"; +import ESC from "../../../svg/ESC.svg"; + +const ModalStart = ({ onClose, setIsMettingStop }) => { + const onClickStart = () => { + setIsMettingStop((prev) => !prev); + onClose() + }; + return ( + +
+
+

+ 회의를 재개하실건가요? +

+ +
+ + + 재개 + + +
+
+ ); +}; + +export default ModalStart; + +const ModalStop = styled.div` + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.25); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +`; + +const Main = styled.div` + background-color: #ffff; + width: 30%; + height: 30%; + border-radius: 12px; + z-index: 10000; + display: flex; + flex-direction: column; + justify-content: space-between; +`; + +const Header = styled.div` + width: 100%; + height: 20%; + display: flex; + justify-content: space-around; + align-items: center; + padding-top: 5%; + gap: 10%; +`; + +const End = styled.div` + width: 100%; + height: 30%; + display: flex; + align-items: center; + justify-content: center; +`; + +const EndButton = styled.button` + width: 90%; + height: 80%; + border: none; + border-radius: 12px; + color: #ffff; +`; diff --git a/blip-project/src/components/Page/Modal/ModalStop.jsx b/blip-project/src/components/Page/Modal/ModalStop.jsx new file mode 100644 index 0000000..711194a --- /dev/null +++ b/blip-project/src/components/Page/Modal/ModalStop.jsx @@ -0,0 +1,83 @@ +import styled from "styled-components"; +import { color } from "../../../style/color"; +import { typography } from "../../../fonts/fonts"; +import ESC from "../../../svg/ESC.svg"; + +const ModalStop = ({ onClose, setIsMettingStop }) => { + const onClickStop = () => { + setIsMettingStop((prev) => !prev); + onClose(); + }; + return ( + +
+
+

+ 회의를 종료하실건가요? +

+ +
+ + + 종료 + + +
+
+ ); +}; + +export default ModalStop; + +const ModalStart = styled.div` + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.25); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +`; + +const Main = styled.div` + background-color: #ffff; + width: 30%; + height: 30%; + border-radius: 12px; + z-index: 10000; + display: flex; + flex-direction: column; + justify-content: space-between; +`; + +const Header = styled.div` + width: 100%; + height: 20%; + display: flex; + justify-content: space-around; + align-items: center; + padding-top: 5%; + gap: 10%; +`; + +const End = styled.div` + width: 100%; + height: 30%; + display: flex; + align-items: center; + justify-content: center; +`; + +const EndButton = styled.button` + width: 90%; + height: 80%; + border: none; + border-radius: 12px; + color: #ffff; +`; diff --git a/blip-project/src/components/Page/MyPage/Modals/emailChangeModal.jsx b/blip-project/src/components/Page/MyPage/Modals/emailChangeModal.jsx new file mode 100644 index 0000000..07d873d --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Modals/emailChangeModal.jsx @@ -0,0 +1,109 @@ +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; +import ESC from "../../../../svg/ESC.svg"; +import Id from "../../../SignUpLogin/id"; +import { useState } from "react"; + +const EmailChangeModal = ({ message, onConfirm, onCancel, onChange }) => { + const [email, setEmail] = useState(""); + const handleChange = (value) => { + setEmail(value); + onChange(value); + }; + return ( +
+
+ +

+ {message} +

+
+
+

+ 이메일 +

+ handleChange(e.target.value)} + style={{ + borderRadius: "12px", + width: "512px", + height: "50px", + textIndent: "20px", + }} + /> +
+ +
+
+
+ ); +}; + +export default EmailChangeModal; diff --git a/blip-project/src/components/Page/MyPage/Modals/emailChangeModal2.jsx b/blip-project/src/components/Page/MyPage/Modals/emailChangeModal2.jsx new file mode 100644 index 0000000..4185390 --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Modals/emailChangeModal2.jsx @@ -0,0 +1,109 @@ +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; +import ESC from "../../../../svg/ESC.svg"; +import Id from "../../../SignUpLogin/id"; +import { useState } from "react"; + +const EmailChangeModal2 = ({ message, onConfirm, onCancel, onChange }) => { + const [email, setEmail] = useState(""); + const handleChange = (value) => { + setEmail(value); + onChange(value); + }; + return ( +
+
+ +

+ {message} +

+
+
+

+ 이메일 +

+ handleChange(e.target.value)} + style={{ + borderRadius: "12px", + width: "512px", + height: "50px", + textIndent: "20px", + }} + /> +
+ +
+
+
+ ); +}; + +export default EmailChangeModal2; diff --git a/blip-project/src/components/Page/MyPage/Modals/idChangeModal.jsx b/blip-project/src/components/Page/MyPage/Modals/idChangeModal.jsx new file mode 100644 index 0000000..209eecb --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Modals/idChangeModal.jsx @@ -0,0 +1,109 @@ +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; +import ESC from "../../../../svg/ESC.svg"; +import Id from "../../../SignUpLogin/id"; +import { useState } from "react"; + +const IdChangeModal = ({ message, onConfirm, onCancel, onChange }) => { + const [id, setId] = useState(""); + const handleChange = (value) => { + setId(value); + onChange(value); + }; + return ( +
+
+ +

+ {message} +

+
+
+

+ 아이디 +

+ handleChange(e.target.value)} + style={{ + borderRadius: "12px", + width: "512px", + height: "50px", + textIndent: "20px", + }} + /> +
+ +
+
+
+ ); +}; + +export default IdChangeModal; diff --git a/blip-project/src/components/Page/MyPage/Modals/imageChangeModal.jsx b/blip-project/src/components/Page/MyPage/Modals/imageChangeModal.jsx new file mode 100644 index 0000000..d203f3e --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Modals/imageChangeModal.jsx @@ -0,0 +1,190 @@ +import { useState, useRef } from "react"; +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; +import ESC from "../../../../svg/ESC.svg"; + +const ImageChangeModal = ({ message, onConfirm, onCancel, onImageSelect }) => { + const [previewImage, setPreviewImage] = useState(null); + const fileInputRef = useRef(null); + + const handleFileSelect = (e) => { + const file = e.target.files[0]; + if (file) { + const reader = new FileReader(); + reader.onload = () => { + setPreviewImage(reader.result); + onImageSelect(file); + }; + reader.readAsDataURL(file); + } + }; + + const triggerFileInput = () => { + fileInputRef.current.click(); + }; + + return ( +
+
+ Close +

+ {message} +

+ +
+ {previewImage ? ( + Preview + ) : ( +
+

+ 프로필 이미지를 선택해주세요 +

+ +
+ )} +
+ + + +
+ {previewImage && ( + + )} + + +
+
+
+ ); +}; + +export default ImageChangeModal; diff --git a/blip-project/src/components/Page/MyPage/Modals/killModal.jsx b/blip-project/src/components/Page/MyPage/Modals/killModal.jsx new file mode 100644 index 0000000..97403e1 --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Modals/killModal.jsx @@ -0,0 +1,109 @@ +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; +import ESC from "../../../../svg/ESC.svg"; +const KillModal = ({ message, onConfirm, onCancel }) => { + return ( +
+
+ +

+ {message} +

+

+ 탈퇴를 위해서는 비밀번호 입력이 필요해요! +

+
+
+

+ 비밀번호 +

+ +
+ +
+
+
+ ); +}; + +export default KillModal; diff --git a/blip-project/src/components/Page/MyPage/Modals/logoutModal.jsx b/blip-project/src/components/Page/MyPage/Modals/logoutModal.jsx new file mode 100644 index 0000000..e0fd3a4 --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Modals/logoutModal.jsx @@ -0,0 +1,87 @@ +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; +import ESC from "../../../../svg/ESC.svg"; +const LogoutModal = ({ message, onConfirm, onCancel }) => { + return ( +
+
+ +

+ {message} +

+

+ 언제든지 다시 로그인할 수 있습니다! +

+
+ +
+
+
+ ); +}; + +export default LogoutModal; diff --git a/blip-project/src/components/Page/MyPage/Modals/nameChangeModal.jsx b/blip-project/src/components/Page/MyPage/Modals/nameChangeModal.jsx new file mode 100644 index 0000000..fd55fae --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Modals/nameChangeModal.jsx @@ -0,0 +1,108 @@ +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; +import ESC from "../../../../svg/ESC.svg"; +import { useState } from "react"; + +const NameChangeModal = ({ message, onConfirm, onCancel, onChange }) => { + const [name, setName] = useState(""); + const handleChange = (value) => { + setName(value); + onChange(value); + }; + return ( +
+
+ +

+ {message} +

+
+
+

+ 이름 +

+ handleChange(e.target.value)} + style={{ + borderRadius: "12px", + width: "512px", + height: "50px", + textIndent: "20px", + }} + /> +
+ +
+
+
+ ); +}; + +export default NameChangeModal; diff --git a/blip-project/src/components/Page/MyPage/Modals/passwordChangeModal.jsx b/blip-project/src/components/Page/MyPage/Modals/passwordChangeModal.jsx new file mode 100644 index 0000000..98e873b --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Modals/passwordChangeModal.jsx @@ -0,0 +1,146 @@ +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; +import ESC from "../../../../svg/ESC.svg"; +import { PassWord } from "../../../SignUpLogin/password"; +import { PasswordCheck } from "../../../SignUpLogin/passwordCheck"; +const PasswordChangeModal = ({ message, onConfirm, onCancel }) => { + return ( +
+
+ +

+ {message} +

+
+
+

+ 현재 비밀번호 +

+ +
+
+

+ 새 비밀번호 +

+ +
+
+

+ 비밀번호 확인 +

+ +
+ +
+
+
+ ); +}; + +export default PasswordChangeModal; diff --git a/blip-project/src/components/Page/MyPage/NeedPage/mainTeamWithoutStart.jsx b/blip-project/src/components/Page/MyPage/NeedPage/mainTeamWithoutStart.jsx new file mode 100644 index 0000000..9b83e2c --- /dev/null +++ b/blip-project/src/components/Page/MyPage/NeedPage/mainTeamWithoutStart.jsx @@ -0,0 +1,38 @@ +import "../../../CSS/MainTeam.css"; +import DateTeam from "../../Src/DateTeam"; +import HeaderTeam from "../../Src/page/HeaderTeam"; +import SidebarTeam from "../../Src/sidebarTeam"; +import MeetingTeam from "../../Src/MeetingTeam"; +import Profiles from "../Profiles/profile"; +import Feedback from "../../Src/page/Feedback"; +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; + +const MainTeamWithoutStart = () => { + return ( + <> + +
+ +
+ +
+

+ 회의 피드백 +

+ +
+
+
+ + +
+
+ + ); +}; + +export default MainTeamWithoutStart; diff --git a/blip-project/src/components/Page/MyPage/NeedPage/mainTeamWithoutStart2.jsx b/blip-project/src/components/Page/MyPage/NeedPage/mainTeamWithoutStart2.jsx new file mode 100644 index 0000000..7740245 --- /dev/null +++ b/blip-project/src/components/Page/MyPage/NeedPage/mainTeamWithoutStart2.jsx @@ -0,0 +1,38 @@ +import "../../../CSS/MainTeam.css"; +import DateTeam from "../../Src/DateTeam"; +import HeaderTeam from "../../Src/page/HeaderTeam"; +import SidebarTeam from "../../Src/sidebarTeam"; +import MeetingTeam from "../../Src/MeetingTeam"; +import Profiles2 from "../Profiles/profile2"; +import Feedback from "../../Src/page/Feedback"; +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; + +const MainTeamWithoutStart2 = () => { + return ( + <> + +
+ +
+ +
+

+ 회의 피드백 +

+ +
+
+
+ + +
+
+ + ); +}; + +export default MainTeamWithoutStart2; diff --git a/blip-project/src/components/Page/MyPage/Profiles/profile.jsx b/blip-project/src/components/Page/MyPage/Profiles/profile.jsx new file mode 100644 index 0000000..41a89a6 --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Profiles/profile.jsx @@ -0,0 +1,188 @@ +import * as S from "../Profiles/profileStyle"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; +import { useState } from "react"; +import LogoutModal from "../Modals/logoutModal"; +import KillModal from "../Modals/killModal"; +import EmailChangeModal from "../Modals/emailChangeModal"; +import IdChangeModal from "../Modals/idChangeModal"; +import PasswordChangeModal from "../Modals/passwordChangeModal"; +import ImageChangeModal from "../Modals/imageChangeModal"; +import profileDefault from "../../../../svg/profileDefault.svg"; + +const Profiles = () => { + const [showLogoutModal, setShowLogoutModal] = useState(false); + const [showKillModal, setShowKillModal] = useState(false); + const [showEmailModal, setEmailChangeModal] = useState(false); + const [showIdModal, setIdChangemModal] = useState(false); + const [showPasswordModal, setPasswordChangeModal] = useState(false); + const [showImageModal, setImageChangeModal] = useState(false); + const [userId, setUserId] = useState("kimchijonmattang11"); + const [newIdInput, setNewIdInput] = useState(""); + const [userEmail, setUserEmail] = useState("aaaaaaaaaaaa@gmail.com"); + const [newEmailInput, setNewEmailInput] = useState(""); + const [profileImage, setProfileImage] = useState(profileDefault); + const [selectedImageFile, setSelectedImageFile] = useState(null); + + const handleLogout = () => { + console.log("로그아웃 완료"); + setShowLogoutModal(false); + }; + const handleKill = () => { + console.log("회원탈퇴 완료"); + setShowKillModal(false); + }; + const handleChangeEmail = () => { + setUserEmail(newEmailInput); + setEmailChangeModal(false); + console.log("이메일 바뀜딘메ㅐㄻㄴ얼;ㅁㄴㅇ", newEmailInput); + }; + const handleChangeId = () => { + setUserId(newIdInput); + setIdChangemModal(false); + console.log("아이디가 바뀌었어용:", newIdInput); + }; + const handleChangePassword = () => { + console.log("비밀번호 바꾸기용용용"); + setPasswordChangeModal(false); + }; + const handleChangeImage = () => { + if (!selectedImageFile) return; + + const imageUrl = URL.createObjectURL(selectedImageFile); + setProfileImage(imageUrl); + setImageChangeModal(false); + + console.log("프로필 이미지 변경 완료:", selectedImageFile); + }; + + return ( + <> + + + + + {userId} + setImageChangeModal(true)}> + 프로필 사진 변경 + + + + + + +

+ 이메일 +

+ + {userEmail} + +
+ { + setEmailChangeModal(true); + }} + > + 수정 + +
+ + + +

+ 아이디 +

+ + {userId} + +
+ setIdChangemModal(true)}> + 수정 + +
+
+ + + + + 비밀번호 변경하기 + + setPasswordChangeModal(true)} + > + 변경하기 + + + + 로그아웃 + setShowLogoutModal(true)}> + 로그아웃 + + + + 회원탈퇴 + setShowKillModal(true)}> + 회원탈퇴 + + + +
+ + {showLogoutModal && ( + setShowLogoutModal(false)} + /> + )} + {showKillModal && ( + setShowKillModal(false)} + /> + )} + + {showEmailModal && ( + setEmailChangeModal(false)} + onChange={setNewEmailInput} + /> + )} + + {showIdModal && ( + setIdChangemModal(false)} + onChange={setNewIdInput} + /> + )} + + {showPasswordModal && ( + setPasswordChangeModal(false)} + /> + )} + + {showImageModal && ( + setImageChangeModal(false)} + onImageSelect={setSelectedImageFile} + /> + )} + + ); +}; + +export default Profiles; diff --git a/blip-project/src/components/Page/MyPage/Profiles/profile2.jsx b/blip-project/src/components/Page/MyPage/Profiles/profile2.jsx new file mode 100644 index 0000000..5628343 --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Profiles/profile2.jsx @@ -0,0 +1,221 @@ +import * as S from "../Profiles/profileStyle2"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; +import { useState } from "react"; +import LogoutModal from "../Modals/logoutModal"; +import KillModal from "../Modals/killModal"; +import EmailChangeModal from "../Modals/emailChangeModal"; +import IdChangeModal from "../Modals/idChangeModal"; +import PasswordChangeModal from "../Modals/passwordChangeModal"; +import ImageChangeModal from "../Modals/imageChangeModal"; +import profileDefault from "../../../../svg/profileDefault.svg"; +import NameChangeModal from "../Modals/nameChangeModal"; + +const Profiles2 = () => { + const [showLogoutModal, setShowLogoutModal] = useState(false); + const [showKillModal, setShowKillModal] = useState(false); + const [showEmailModal, setEmailChangeModal] = useState(false); + const [showIdModal, setIdChangemModal] = useState(false); + const [showPasswordModal, setPasswordChangeModal] = useState(false); + const [showImageModal, setImageChangeModal] = useState(false); + const [showNameModal, setNameChangeModal] = useState(false); + const [userId, setUserId] = useState("kimchijonmattang11"); + const [newIdInput, setNewIdInput] = useState(""); + const [userEmail, setUserEmail] = useState("aaaaaaaaaaaa@gmail.com"); + const [newEmailInput, setNewEmailInput] = useState(""); + const [profileImage, setProfileImage] = useState(profileDefault); + const [selectedImageFile, setSelectedImageFile] = useState(null); + const [userName, setUserName] = useState("손희찬"); + const [newNameInput, setNewNameInput] = useState(""); + + const handleLogout = () => { + console.log("로그아웃 완료"); + setShowLogoutModal(false); + }; + const handleKill = () => { + console.log("회원탈퇴 완료"); + setShowKillModal(false); + }; + const handleChangeEmail = () => { + console.log("인증번호~~"); + setEmailChangeModal(false); + }; + const handleChangeId = () => { + setUserId(newIdInput); + setIdChangemModal(false); + console.log("아이디가 바뀌었어용:", newIdInput); + }; + const handleChangePassword = () => { + console.log("비밀번호 바꾸기용용용"); + }; + const handleChangeImage = () => { + if (!selectedImageFile) return; + + const imageUrl = URL.createObjectURL(selectedImageFile); + setProfileImage(imageUrl); + setImageChangeModal(false); + + console.log("프로필 이미지 변경 완료:", selectedImageFile); + }; + const handleChangeName = () => { + setUserName(newNameInput); + setNameChangeModal(false); + console.log("이름이 바뀌었어용"); + }; + + return ( + <> + + + + + {userName} + {userId} + setImageChangeModal(true)}> + 프로필 사진 변경 + + + + + + +

+ 이메일 +

+ + {userEmail} + +
+ { + setEmailChangeModal(true); + }} + > + 수정 + +
+ + + +

+ 아이디 +

+ + {userId} + +
+ setIdChangemModal(true)}> + 수정 + +
+ + + +

+ 이 스페이스에서 사용하는 이름 +

+ + {userName} + +
+ setNameChangeModal(true)}> + 수정 + +
+
+ + + + + 비밀번호 변경하기 + + setPasswordChangeModal(true)} + > + 변경하기 + + + + 로그아웃 + setShowLogoutModal(true)}> + 로그아웃 + + + + 회원탈퇴 + setShowKillModal(true)}> + 회원탈퇴 + + + +
+ + {showLogoutModal && ( + setShowLogoutModal(false)} + /> + )} + {showKillModal && ( + setShowKillModal(false)} + /> + )} + + {showEmailModal && ( + setEmailChangeModal(false)} + onChange={setNewEmailInput} + /> + )} + + {showIdModal && ( + setIdChangemModal(false)} + onChange={setNewIdInput} + /> + )} + + {showPasswordModal && ( + setPasswordChangeModal(false)} + /> + )} + + {showImageModal && ( + setImageChangeModal(false)} + onImageSelect={setSelectedImageFile} + /> + )} + + {showNameModal && ( + setNameChangeModal(false)} + onChange={setNewNameInput} + /> + )} + + ); +}; + +export default Profiles2; diff --git a/blip-project/src/components/Page/MyPage/Profiles/profileStyle.jsx b/blip-project/src/components/Page/MyPage/Profiles/profileStyle.jsx new file mode 100644 index 0000000..412f376 --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Profiles/profileStyle.jsx @@ -0,0 +1,172 @@ +import styled from "styled-components"; +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; +export const Line = styled.div` + display: flex; + flex-direction: column; + align-items: center; + border: 1px solid ${color.GrayScale[2]}; + width: 1114px; + height: 526px; + border-radius: 12px; + position: relative; + margin-bottom: 390px; +`; + +export const Profile = styled.div` + width: 140px; + height: 140px; + border-radius: 100px; + border: 0.5px solid ${color.GrayScale[1]}; + position: relative; + width: 150px; + height: 120px; + border-radius: 50%; + background-size: cover; + background-position: center; + background-repeat: no-repeat; + border-radius: 50%; + border: 1px solid black; + margin-bottom: 30px; +`; + +/* export const Name = styled.p` + position: relative; + font: ${typography.Header2}; +`; */ + +export const Id = styled.p` + position: relative; + font: ${typography.Header2}; + color: ${color.GrayScale[8]}; + margin-left: 6px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: calc(100% - 150px); + margin-bottom: 25px; +`; +export const ProfileChangeButton = styled.button` + position: absolute; + right: 35px; + width: 111px; + height: 34px; + border-radius: 12px; + border: none; + background-color: ${color.Main[4]}; + color: ${color.White}; + font: ${typography.Button3}; +`; +export const InfoLine = styled.div` + width: 1066px; + height: 212px; + border: 1px solid ${color.GrayScale[2]}; + position: relative; + border-radius: 12px; + margin-top: 5px; +`; +export const Email = styled.p``; +export const EmailChangeButton = styled.button` + width: 69px; + height: 34px; + border-radius: 12px; + background-color: ${color.Main[4]}; + font: ${typography.Button3}; + border: none; + color: ${color.White}; + margin-right: 36px; +`; +export const IdChangeButton = styled.button` + width: 69px; + height: 34px; + border-radius: 12px; + background-color: ${color.Main[4]}; + font: ${typography.Button3}; + border: none; + color: ${color.White}; + margin-right: 36px; +`; +export const ChangeLine = styled.div` + display: flex; + justify-content: start; + align-items: center; + width: 1066px; + height: 80px; + border: 1px solid ${color.GrayScale[2]}; + position: relative; + border-radius: 12px; + margin-top: 16px; +`; + +export const ProfileContainer = styled.div` + /* display: flex; + align-items: center; + gap: 24px; */ + display: flex; + align-items: center; + justify-content: start; + gap: 24px; + width: 1066px; + margin-top: 44px; +`; +export const PasswordChangeButton = styled.button` + width: 134px; + height: 34px; + border-radius: 12px; + color: ${color.White}; + background-color: ${color.Main[4]}; + border: none; +`; +export const LogoutButton = styled.button` + width: 134px; + height: 34px; + border-radius: 12px; + color: ${color.White}; + background-color: ${color.Main[4]}; + border: none; +`; +export const KillButton = styled.button` + width: 134px; + height: 34px; + border-radius: 12px; + color: ${color.White}; + background-color: ${color.Main[4]}; + border: none; +`; +export const SmallId = styled.p` + position: relative; +`; +export const TextWithButtonContainer = styled.div` + position: relative; + width: 100%; + display: flex; + align-items: center; +`; +export const InfoItem = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + margin-top: 16px; +`; +export const TextBlock = styled.div` + display: flex; + flex-direction: column; + gap: 8px; + transform: translateX(24px); +`; +export const ChangePassword = styled.p` + margin-bottom: 3px; +`; +export const Logout = styled.p` + margin-bottom: 3px; +`; +export const Kill = styled.p` + margin-bottom: 3px; +`; +export const ChangeItem = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; +`; diff --git a/blip-project/src/components/Page/MyPage/Profiles/profileStyle2.jsx b/blip-project/src/components/Page/MyPage/Profiles/profileStyle2.jsx new file mode 100644 index 0000000..8f0a29b --- /dev/null +++ b/blip-project/src/components/Page/MyPage/Profiles/profileStyle2.jsx @@ -0,0 +1,181 @@ +import styled from "styled-components"; +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; + +export const Line = styled.div` + display: flex; + flex-direction: column; + align-items: center; + border: 1px solid ${color.GrayScale[2]}; + width: 956px; + height: 526px; + border-radius: 12px; + position: relative; +`; + +export const Profile = styled.div` + width: 150px; + height: 120px; + border-radius: 50%; + background-size: cover; + background-position: center; + background-repeat: no-repeat; + border: 1px solid black; + margin-left: 80px; +`; + +export const Id = styled.p` + position: relative; + font: ${typography.Body1}; + color: ${color.GrayScale[8]}; + margin-left: 6px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: calc(100% - 150px); +`; + +export const ProfileChangeButton = styled.button` + position: absolute; + right: 110px; + width: 111px; + height: 34px; + border-radius: 12px; + border: none; + background-color: ${color.Main[4]}; + color: ${color.White}; + font: ${typography.Button3}; +`; + +export const InfoLine = styled.div` + width: 908px; + height: 212px; + border: 1px solid ${color.GrayScale[2]}; + position: relative; + border-radius: 12px; + margin-top: 16px; +`; + +export const Email = styled.p``; + +export const EmailChangeButton = styled.button` + width: 69px; + height: 34px; + border-radius: 12px; + background-color: ${color.Main[4]}; + font: ${typography.Button3}; + border: none; + color: ${color.White}; + margin-right: 36px; +`; + +export const IdChangeButton = styled.button` + width: 69px; + height: 34px; + border-radius: 12px; + background-color: ${color.Main[4]}; + font: ${typography.Button3}; + border: none; + color: ${color.White}; + margin-right: 36px; +`; + +export const ChangeLine = styled.div` + display: flex; + justify-content: start; + align-items: center; + width: 908px; + height: 80px; + border: 1px solid ${color.GrayScale[2]}; + position: relative; + border-radius: 12px; + margin-top: 16px; +`; + +export const ProfileContainer = styled.div` + display: flex; + align-items: center; + justify-content: start; + gap: 24px; + width: 1066px; + margin-top: 44px; +`; + +export const PasswordChangeButton = styled.button` + width: 134px; + height: 34px; + border-radius: 12px; + color: ${color.White}; + background-color: ${color.Main[4]}; + border: none; +`; + +export const LogoutButton = styled.button` + width: 134px; + height: 34px; + border-radius: 12px; + color: ${color.White}; + background-color: ${color.Main[4]}; + border: none; +`; + +export const KillButton = styled.button` + width: 134px; + height: 34px; + border-radius: 12px; + color: ${color.White}; + background-color: ${color.Main[4]}; + border: none; +`; + +export const SmallId = styled.p` + position: relative; +`; + +export const TextWithButtonContainer = styled.div` + position: relative; + width: 100%; + display: flex; + align-items: center; + flex-direction: start; +`; + +export const InfoItem = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + margin-top: 16px; +`; + +export const TextBlock = styled.div` + display: flex; + flex-direction: column; + gap: 8px; + transform: translateX(24px); +`; + +export const ChangePassword = styled.p` + margin-bottom: 3px; + white-space: nowrap; +`; + +export const Logout = styled.p` + margin-bottom: 3px; +`; + +export const Kill = styled.p` + margin-bottom: 3px; +`; + +export const ChangeItem = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; +`; + +export const Name = styled.p` + font: ${typography.Header2}; + color: ${color.GrayScale[8]}; +`; diff --git a/blip-project/src/components/Page/MyPage/myPageNoTeam.jsx b/blip-project/src/components/Page/MyPage/myPageNoTeam.jsx new file mode 100644 index 0000000..f32c7bd --- /dev/null +++ b/blip-project/src/components/Page/MyPage/myPageNoTeam.jsx @@ -0,0 +1,68 @@ +import { useEffect, useState } from "react"; +import MTeamJoinNo from "../Main/MainTeamJoinNo"; +import HeaderTeam from "../Src/page/HeaderTeam"; +import Feedback from "../Src/page/Feedback"; +import MeetingContent from "../Src/page/MeetingContent"; +import SidebarTeam from "../Src/sidebarTeam"; +import DateTeamJoinNo from "../Src/DateTeam"; +import MainTeam from "../Main/MainTeam"; +import { TeamDel } from "../Main/Main"; +import DateTeam from "../Src/DateTeam"; +import MeetingTeam from "../Src/MeetingTeam"; +import MainTeamWithoutStart from "./NeedPage/mainTeamWithoutStart"; +import "../../CSS/myPage.css"; +import { useParams } from "react-router-dom"; +import { instance } from "../../../apis/instance"; + +const MyPageNoTeam = () => { + const [image, setImage] = useState(null); + const [Owner, setOwner] = useState(false); + const [join, setJoin] = useState(false); + const [itemId, setItemId] = useState(null); + + const teamId = itemId || "원하는팀ID"; + const accessToken = localStorage.getItem("accessToken"); + + const { userId } = useParams(); + const [userInfo, setUserInfo] = useState(null); + + useEffect(() => { + console.log("userId:", userId); + console.log("accessToken:", accessToken); + + if (!userId || !accessToken) return; + + instance + .get(`/users/${userId}/mypage`, { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }) + .then((res) => { + console.log("API 응답:", res.data); + setUserInfo(res.data); + }) + .catch((err) => { + console.error("API 에러:", err); + }); + }, [userId]); + + const teamDelContext = { + image, + setImage, + itemId, + Owner, + setOwner, + join, + setJoin, + userInfo, + }; + + return ( + + + + ); +}; + +export default MyPageNoTeam; diff --git a/blip-project/src/components/Page/MyPage/myPageTeam.jsx b/blip-project/src/components/Page/MyPage/myPageTeam.jsx new file mode 100644 index 0000000..d783a3d --- /dev/null +++ b/blip-project/src/components/Page/MyPage/myPageTeam.jsx @@ -0,0 +1,68 @@ +import { useEffect, useState } from "react"; +import MTeamJoinNo from "../Main/MainTeamJoinNo"; +import HeaderTeam from "../Src/page/HeaderTeam"; +import Feedback from "../Src/page/Feedback"; +import MeetingContent from "../Src/page/MeetingContent"; +import SidebarTeam from "../Src/sidebarTeam"; +import DateTeamJoinNo from "../Src/DateTeam"; +import MainTeam from "../Main/MainTeam"; +import { TeamDel } from "../Main/Main"; +import DateTeam from "../Src/DateTeam"; +import MeetingTeam from "../Src/MeetingTeam"; +import MainTeamWithoutStart2 from "./NeedPage/mainTeamWithoutStart2"; +import "../../CSS/myPage.css"; +import { useParams } from "react-router-dom"; +import { instance } from "../../../apis/instance"; + +const MyPageTeam = () => { + const [image, setImage] = useState(null); + const [Owner, setOwner] = useState(false); + const [join, setJoin] = useState(false); + const [itemId, setItemId] = useState(null); + + const teamId = itemId || "원하는팀ID"; + const accessToken = localStorage.getItem("accessToken"); + + const { userId } = useParams(); + const [userInfo, setUserInfo] = useState(null); + + useEffect(() => { + console.log("userId:", userId); + console.log("accessToken:", accessToken); + + if (!userId || !accessToken) return; + + instance + .get(`/users/${userId}/mypage`, { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }) + .then((res) => { + console.log("API 응답:", res.data); + setUserInfo(res.data); + }) + .catch((err) => { + console.error("API 에러:", err); + }); + }, [userId]); + + const teamDelContext = { + image, + setImage, + itemId, + Owner, + setOwner, + join, + setJoin, + userInfo, + }; + + return ( + + + + ); +}; + +export default MyPageTeam; diff --git a/blip-project/src/components/Page/Src/DateTeam.jsx b/blip-project/src/components/Page/Src/DateTeam.jsx new file mode 100644 index 0000000..ca8fb8e --- /dev/null +++ b/blip-project/src/components/Page/Src/DateTeam.jsx @@ -0,0 +1,127 @@ +import "../../CSS/DateTeam.css"; +import { color } from "../../../style/color"; +import { typography } from "../../../fonts/fonts"; +import { useState } from "react"; + +const DateTeamJoinNo = () => { + const [currentDate, setCurrentDate] = useState(new Date()); + const [selectedDate, setSelectedDate] = useState(null); + + const year = currentDate.getFullYear(); + const month = currentDate.getMonth(); + + const firstDayOfMonth = new Date(year, month, 1); + + const startDay = new Date(firstDayOfMonth); + startDay.setDate(1 - firstDayOfMonth.getDay()); + + const lastDayOfMonth = new Date(year, month + 1, 0); + + const endDay = new Date(lastDayOfMonth); + endDay.setDate(lastDayOfMonth.getDate() + (6 - lastDayOfMonth.getDay())); + + const groupDatesByWeek = (startDay, endDay) => { + const weeks = []; + let currentWeek = []; + let currentDay = new Date(startDay); + + while (currentDay <= endDay) { + currentWeek.push(new Date(currentDay)); + if (currentWeek.length === 7 || currentDate.getDay() === 6) { + weeks.push(currentWeek); + currentWeek = []; + } + currentDay.setDate(currentDay.getDate() + 1); + } + + if (currentWeek.length > 0) { + weeks.push(currentWeek); + } + + return weeks; + }; + + const handlePrevMonth = () => { + setCurrentDate( + new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1) + ); + }; + + const handleNextMonth = () => { + setCurrentDate( + new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1) + ); + }; + + const handleDateClick = (date) => { + setSelectedDate(date); + }; + + return ( + <> +
+
+
+

{year}년

{/* 년도 */} +

+ {currentDate.toLocaleString("default", { month: "long" })} +

+ {/* 월 */} +
+
+ + +
+
+
+
+ {["일", "월", "화", "수", "목", "금", "토"].map((day) => ( +
+ {day} +
+ ))} + {groupDatesByWeek(startDay, endDay).map((week, weekIndex) => ( +
+ {week.map((date, dayIndex) => { + const isSelected = + selectedDate && + date.toDateString() === selectedDate.toDateString(); // 선택된 날짜인지 확인 + return ( +
handleDateClick(date)} // 날짜 클릭 이벤트 + > + {date.getDate()} +
+ ); + })} +
+ ))} +
+
+ + ); +}; + +export default DateTeamJoinNo; diff --git a/blip-project/src/components/Page/Src/MeetingTeam.jsx b/blip-project/src/components/Page/Src/MeetingTeam.jsx new file mode 100644 index 0000000..ed5ec06 --- /dev/null +++ b/blip-project/src/components/Page/Src/MeetingTeam.jsx @@ -0,0 +1,126 @@ +import "../../CSS/MeetingTeam.css"; +import { color } from "../../../style/color"; +import { typography } from "../../../fonts/fonts"; +import { useState, useContext } from "react"; +import { UseStateContext } from "../../../Router"; +import { TeamDel } from "../Main/Main"; +import { SidebarContext } from "../../../Router"; +import { Call } from "../../../Router"; +import ModalMeeting from "../Modal/ModalMeeting"; +import MettingContent from "./page/MeetingContent"; + +const MeetingTeam = () => { + const { discord, meetingEnd, setMeetingEnd } = useContext(UseStateContext); + + const { todos } = useContext(SidebarContext); + + const { Owner, itemId, join } = useContext(TeamDel); + + const { recordedChunks, setIsUploading } = useContext(Call); + + const [isModalOpen, setIsModalOpen] = useState(false); + const modalOpen = () => setIsModalOpen(true); + const modalClose = () => setIsModalOpen(false); + + const uploadRecording = async () => { + if (!meetingEnd) { + setMeetingEnd((preState) => !preState); + console.log("시발련련"); + } + + if (!Owner) return; + + if (recordedChunks.length === 0) return; + + const blob = new Blob(recordedChunks, { type: "audio/webm" }); + const formData = new FormData(); + formData.append("file", blob, "recording.webm"); + + try { + setIsUploading(true); + const response = await fetch("링크", { + method: "post", + body: formData, + }); + + if (response.ok) { + console.log("파일 업로드 성공"); + } else { + console.error("업로드 실패", response.statusText); + } + } catch (error) { + console.log("업로드 중 에러"); + } finally { + setIsUploading(false); + } + }; + + const handleLeveMeeting = () => { + if (Owner) { + uploadRecording(); + } + setMeetingEnd(true); + console.log("회의 종료"); + }; + + return ( + <> +
+
+ 지난 회의 내용 요약 +
+ +
+ {discord ? ( + + ) : !Owner && todos.length > 1 && !join && itemId != 0 ? ( + + ) : ( + + )} + {isModalOpen && } + + ); +}; + +export default MeetingTeam; diff --git a/blip-project/src/components/Page/Src/Member.jsx b/blip-project/src/components/Page/Src/Member.jsx new file mode 100644 index 0000000..63cae98 --- /dev/null +++ b/blip-project/src/components/Page/Src/Member.jsx @@ -0,0 +1,80 @@ +import "../../CSS/Member.css"; +import { color } from "../../../style/color"; +import { typography } from "../../../fonts/fonts"; +import { useContext, useState } from "react"; +import { TeamDel } from "../Main/Main"; +import { UseStateContext } from "../../../Router"; +import { FindId } from "../Main/Main"; +import MemberSVG from "../../../svg/member.svg"; +import Setting from "../../../svg/setting.svg"; +import Plus from "../../../svg/plus.svg"; + +const Member = ({ filterId }) => { + const { itemId, image } = useContext(TeamDel) || {}; + const { + setSetting, + isAlarm, + setIsAlarm, + isLetter, + setIsLetter, + isFeedback, + setIsFeedback, + isKeyword, + setIsKeyword, + } = useContext(UseStateContext); + const { targetId, setTargetId } = useContext(FindId); + + const onClickSetting = () => { + setSetting((preState) => !preState); + if (itemId !== targetId && image) setTargetId(null,"dafmiaubihsjkf") + console.log(targetId); + if (isAlarm === true) { + setIsAlarm((preState) => !preState); + } else if (isLetter === true) { + setIsLetter((preState) => !preState); + } else if (isFeedback === true) { + setIsFeedback((preState) => !preState); + } else if (isKeyword === true) { + setIsKeyword((preState) => !preState); + } + }; + + return ( + <> +
+
+ {(itemId % 2 === 0 || filterId % 2 === 0) && itemId !== 0 ? ( + <> +
+ Team Blip + +
+
+ + +
+ + ) : ( + <> +
+ Team Blip +
+
+ +
+ + )} +
+
+
+ + ); +}; + +export default Member; diff --git a/blip-project/src/components/Page/Src/function/graph.jsx b/blip-project/src/components/Page/Src/function/graph.jsx new file mode 100644 index 0000000..4d5fdce --- /dev/null +++ b/blip-project/src/components/Page/Src/function/graph.jsx @@ -0,0 +1,78 @@ +import { color } from "../../../../style/color"; +import { typography } from "../../../../fonts/fonts"; +import React from "react"; +import ReactApexChart from "react-apexcharts"; +import GraphImg from "../../../../svg/Graph.svg"; + +const Graph = () => { + const [state, setState] = React.useState({ + series: [5, 95], // 두 개의 값을 사용 + options: { + chart: { + type: "donut", + }, + labels: [], // 레이블을 빈 배열로 설정하여 외부 레이블 제거 + plotOptions: { + pie: { + donut: { + size: "60%", // 도넛 크기 설정 + labels: { + show: true, // 가운데 값 표시 + name: { + show: false, // 이름은 숨김 + }, + value: { + show: true, // 값 표시 + fontSize: "22px", // 값의 폰트 크기 + fontWeight: "bold", // 값의 폰트 굵기 + color: color.Main[4], // 값의 색상 + }, + total: { + show: true, // 총합 표시하지 않음 + label: "Total", // 이 부분은 총합 레이블 설정 + formatter: function (w) { + return `${w.globals.series[1]}%`; // 첫 번째 값만 표시 + }, + }, + }, + }, + }, + }, + dataLabels: { + enabled: false, // 데이터 라벨을 비활성화하여 값만 나타나게 함 + }, + legend: { + show: false, + }, + colors: [color.Main[0], color.Main[4]], + }, + }); + return ( +
+
+
+
회의 참여율 확인하기
+

+ 가장 최근 회의율은 95%입니다 +

+
+
+ +
+
+
+ +
+ ); +}; + +export default Graph; diff --git a/blip-project/src/components/Page/Src/function/jitsiMeet.jsx b/blip-project/src/components/Page/Src/function/jitsiMeet.jsx new file mode 100644 index 0000000..adbc0f4 --- /dev/null +++ b/blip-project/src/components/Page/Src/function/jitsiMeet.jsx @@ -0,0 +1,279 @@ +import React, { useState, useEffect, useContext } from "react"; +import "../../../CSS/Grid.css"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; +import { TeamDel } from "../../Main/Main"; +import { UseStateContext } from "../../../../Router"; +import { DiscordContext } from "../../../../Router"; +import { Call } from "../../../../Router"; +import NoMike from "../../../../svg/NoMike.svg"; +import NoCamera from "../../../../svg/NoCamera.svg"; +import Mike from "../../../../svg/Mike.svg"; +import Camera from "../../../../svg/DisCamera.svg"; + +const SpeechRecognition = + window.SpeechRecognition || window.webkitSpeechRecognition; + +const JitsiMeetWithGrid = ({ setIsMettingStop }) => { + const { itemId } = useContext(TeamDel); + const { isMike, setIsMike, isCamera, setIsCamera } = + useContext(UseStateContext); + const { videoRef, stream, setStream } = useContext(DiscordContext); + const { recorder, setRecorder, setRecordedChunks } = useContext(Call); + + const apiUrl = import.meta.env.VITE_API_URL_URL_; + + const captureAndSendImage = () => { + if (!videoRef.current) return; + + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d"); + + canvas.width = videoRef.current.videoWidth; + canvas.height = videoRef.current.videoHeight; + + context.drawImage(videoRef.current, 0, 0, canvas.width, canvas.height); + + const imageData = canvas.toDataURL("image/jpeg"); + + const url = `${apiUrl}/data`; + const accessToken = "토큰 값"; + + fetch(url, { + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify({ image: imageData }), + //string으로 전환입니당~ + }) + .then((response) => response.json()) + .then((data) => { + console.log("이미지 전송 성공", data); + }) + .catch((error) => { + console.error("이미지 전송 실패:", error); + }); + }; + + const recognition = new SpeechRecognition(); + recognition.lang = "ko-KR"; + recognition.continuous = true; + recognition.interimResults = true; + + useEffect(() => { + const captureInterval = setInterval(() => { + captureAndSendImage(); + }, 100); + + const script = document.createElement("script"); + script.src = ""; + script.async = true; + + script.onload = () => { + const domain = "192.168.1.42"; + const options = { + roomName: "TestRoom", + width: "100%", + height: "100%", + parentNode: document.querySelector("#jitsi-iframe-container"), + configOverwrite: { + startWithAudioMuted: false, + startWithVideoMuted: false, + enableWelcomePage: false, + }, + interfaceConfigOverwrite: { + filmStripOnly: false, + }, + }; + + const api = new window.JitsiMeetExternalAPI(domain, options); + + api.addEventListener("videoConferenceJoined", () => { + const stream = api + .getLocalTracks() + .find((track) => track.getType() === "audio").jitsiTrack._track; + const mediaRecorder = new MediaRecorder(stream); + + mediaRecorder.ondataavailable = (event) => { + const audioBlob = event.data; + const audioUrl = URL.createObjectURL(audioBlob); + console.log("녹음된 오디오 URL:", audioUrl); + // 오디오 저장이나 처리 로직을 추가 + }; + + // 회의 시작 시 녹음 시작 + mediaRecorder.start(); + setRecorder(mediaRecorder); + console.log("녹음 시작"); + + // 회의 종료 시 녹음 중지 + api.addEventListener("videoConferenceLeft", () => { + mediaRecorder.stop(); + }); + }); + }; + + script.onerror = (error) => { + console.error("Jitsi API 로딩 실패:", error); + alert("Jitsi API 로딩 실패: " + (error.message || "알 수 없는 오류")); + }; + + document.head.appendChild(script); + + return () => { + const scriptElement = document.querySelector('script[src=""]'); + if (scriptElement) { + document.head.removeChild(scriptElement); + } + clearInterval(captureInterval); + }; + }, [videoRef]); + + useEffect(() => { + if (setIsMettingStop) { + // 회의 중지 시 녹음 중지 + if (recorder && recorder.state !== "inactive") { + recorder.stop(); + console.log("회의 종료: 녹음 중지"); + } + } else { + // 회의 시작 시 녹음 시작 + if (recorder && recorder.state === "inactive") { + startRecording(); + } + } + }, [setIsMettingStop, recorder]); + + const onClickMike = () => { + if (isMike) { + recorder.stop(); + setIsMike(false); + } else { + startRecording(); + setIsMike(true); + } + }; + + const onClickCamera = () => { + setIsCamera((preState) => !preState); + }; + + const startRecording = () => { + if (!stream) return; + + const mediaRecorder = new MediaRecorder(stream); + setRecorder(mediaRecorder); + + mediaRecorder.ondataavailable = (e) => { + if (e.data.size > 0) { + setRecordedChunks((preV) => [...preV, e.data]); + } + }; + + mediaRecorder.start(); + console.log("녹음 시작"); + }; + + return ( +
+ {users.length > 1 && users.length % 2 === 1 ? ( + <> + {users.slice(0, users.length - 1).map((user, index) => ( +
+ {isCamera ? ( +
+ ))} +
+
+ {users[users.length - 1].isCameraOn && isCamera ? ( +
+
+ + ) : ( + <> + {users.map((user) => ( +
+ {isCamera ? ( +
+ ))} + + )} + {/* Jitsi iframe container */} +
+
+ ); +}; + +export default JitsiMeetWithGrid; diff --git a/blip-project/src/components/Page/Src/function/useMike.jsx b/blip-project/src/components/Page/Src/function/useMike.jsx new file mode 100644 index 0000000..d5b6df2 --- /dev/null +++ b/blip-project/src/components/Page/Src/function/useMike.jsx @@ -0,0 +1,55 @@ +import { useState, useEffect, useContext } from "react"; +import { UseStateContext, Call } from "../../../../Router"; + +const UseMike = (stream) => { + const { isMike, setIsMike } = useContext(UseStateContext); + + const { recorder, setRecorder } = useContext(Call); + + const [recordedChunks, setRecordedChunks] = useState([]); + + useEffect(() => { + if (isMike && !recorder) { + startRecording(); + } else if (!isMike && recorder) { + stopRecording(); + } + }, [isMike]); + + const startRecording = () => { + if (!stream) return; + + const mediaRecorder = new MediaRecorder(stream); + setRecorder(mediaRecorder); + + if (!isMike) { + mediaRecorder.ondataavailable = (e) => { + if (e.data.size > 0) { + setRecordedChunks((preV) => [...preV, e.data]); + } + }; + + if (!isMike) { + mediaRecorder.start(); + console.log("녹음 시작"); + setIsMike((preState) => !preState); + } + } + }; + + const stopRecording = () => { + if (isMike && recorder) { + recorder.stop(); + console.log("녹음 중지"); + setIsMike((preState) => !preState); + } + }; + + const toggleMike = () => { + setIsMike((preV) => !preV); + }; + + return { isMike, toggleMike, recordedChunks }; +}; + +export default UseMike; diff --git a/blip-project/src/components/Page/Src/metting/MeetingTeam.jsx b/blip-project/src/components/Page/Src/metting/MeetingTeam.jsx new file mode 100644 index 0000000..9c61de0 --- /dev/null +++ b/blip-project/src/components/Page/Src/metting/MeetingTeam.jsx @@ -0,0 +1,83 @@ +import "./CSS/MeetingTeam.css"; +import { color } from "../../../style/color"; +import { typography } from "../../../fonts/fonts"; +import { useState, useContext } from "react"; +import { useLocation } from "react-router-dom"; +import { UseStateContext } from "../../../Router"; +import ModalMeeting from "../../Modal/ModalMeeting"; +import MettingContent from "./page/MeetingContent"; + +const MeetingTeam = () => { + const location = useLocation(); + const [isModalOpen, setIsModalOpen] = useState(false); + const { discord, meetingEnd, setMeetingEnd } = useContext(UseStateContext); + const modalOpen = () => setIsModalOpen(true); + const modalClose = () => setIsModalOpen(false); + + const onClickMeetingEnd = () => { + if (!meetingEnd) { + setMeetingEnd((preState) => !preState); + } + }; + + return ( + <> +
+
+ 지난 회의 내용 요약 +
+ +
+ {discord ? ( + + ) : location.pathname === "/TeamOwner" ? ( + + ) : ( + + )} + {isModalOpen && } + + ); +}; + +export default MeetingTeam; diff --git a/blip-project/src/components/Page/Src/page/AlarmTeam.jsx b/blip-project/src/components/Page/Src/page/AlarmTeam.jsx new file mode 100644 index 0000000..40d7ad8 --- /dev/null +++ b/blip-project/src/components/Page/Src/page/AlarmTeam.jsx @@ -0,0 +1,25 @@ +import "../../../CSS/AlarmTeam.css"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; +import { useLocation } from "react-router-dom"; + +const Alarm = () => { + const location = useLocation(); + return ( + <> +
+

+ 아직 받은 알람이 없어요 +

+
+ + ); +}; + +export default Alarm; diff --git a/blip-project/src/components/Page/Src/page/Discord.jsx b/blip-project/src/components/Page/Src/page/Discord.jsx new file mode 100644 index 0000000..c5ab43b --- /dev/null +++ b/blip-project/src/components/Page/Src/page/Discord.jsx @@ -0,0 +1,155 @@ +import "../../../CSS/Discord.css"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; +import DisAlarm from "../../../../svg/DisAlarm.svg"; +import NoMike from "../../../../svg/NoMike.svg"; +import NoCamera from "../../../../svg/NoCamera.svg"; +import Mike from "../../../../svg/Mike.svg"; +import Camera from "../../../../svg/DisCamera.svg"; +import Fullscreen from "../../../../svg/FullScreen.svg"; +import X from "../../../../svg/X.svg"; +import MettingStop from "../../../../svg/MettingStop.svg"; +import MettingStart from "../../../../svg/MettingStart.svg"; +import ModalStop from "../../Modal/ModalStop"; +import ModalStart from "../../Modal/ModalStart"; +import JitsiMeet from "../function/jitsiMeet"; +import { useContext, useState } from "react"; +import { TeamDel } from "../../Main/Main"; +import { UseStateContext } from "../../../../Router"; +import { DiscordContext } from "../../../../Router"; +import { FindId } from "../../Main/Main"; + +const Discord = () => { + const { itemId } = useContext(TeamDel); + const [isMettingStop, setIsMettingStop] = useState(false); + + const { targetId } = useContext(FindId); + + const { + isMike, + setIsMike, + isCamera, + setIsCamera, + FullScreen, + setFullScreen, + setDiscord, + meetingEnd, + setMeetingEnd, + } = useContext(UseStateContext); + + const { setIsListening } = useContext(DiscordContext); + + const onClickMike = () => { + setIsMike((preState) => !preState); + setIsListening((preState) => !preState); + }; + + const onClickCamera = () => { + setIsCamera((preState) => !preState); + }; + + const onClickFull = () => { + setFullScreen((preState) => !preState); + }; + + const onClickEnd = () => { + setMeetingEnd((preState) => !preState); + setDiscord((preState) => !preState); + }; + + const [isModalOpen, setIsModalOpen] = useState(false); + const [isModalStart, setIsModalStart] = useState(false); + + const openModalStop = () => setIsModalOpen(true); + const closeModal = () => setIsModalOpen(false); + + const openModalStart = () => setIsModalStart(true); + const IsCloseModal = () => setIsModalStart(false); + + return ( + <> + {meetingEnd ? ( +
+
+
+ +
+
+
회의가 종료되었어요.
+

+ BLIP이 회의를 요약해서 알려드릴게요! +

+
+
+
+ ) : ( + <> + {itemId === targetId ? ( +
+
+ +
+
+ <> +
+ + +
+ +
+
+ + +
+ +
+
+ {isModalStart && ( + + )} + {isModalOpen && ( + + )} +
+ ) : ( + "" + )} + + )} + + ); +}; + +export default Discord; diff --git a/blip-project/src/components/Page/Src/page/Feedback.jsx b/blip-project/src/components/Page/Src/page/Feedback.jsx new file mode 100644 index 0000000..5297933 --- /dev/null +++ b/blip-project/src/components/Page/Src/page/Feedback.jsx @@ -0,0 +1,23 @@ +import "../../../CSS/Feedback.css"; +import PropTypes from "prop-types"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; + +const Feedback = ({ message, isEmpty = true }) => { + return ( + <> +
+

+ {isEmpty ? message || "아직 받은 피드백이 없어요" : message} +

+
+ + ); +}; + +Feedback.prototype = { + message: PropTypes.string, + isEmpty: PropTypes.bool, +}; + +export default Feedback; diff --git a/blip-project/src/components/Page/Src/page/HeaderTeam.jsx b/blip-project/src/components/Page/Src/page/HeaderTeam.jsx new file mode 100644 index 0000000..c41b61b --- /dev/null +++ b/blip-project/src/components/Page/Src/page/HeaderTeam.jsx @@ -0,0 +1,67 @@ +import "../../../CSS/HeaderTeam.css"; +import Alarm from "../../../../svg/alarm.svg"; +import blackLogo from "../../../../svg/blackLogo.svg"; +import Letter from "../../../../svg/letter.svg"; +import { useNavigate } from "react-router-dom"; +import { useContext } from "react"; +import { UseStateContext } from "../../../../Router"; + +const HeaderTeam = () => { + const nav = useNavigate(); + const { + setting, + setSetting, + isAlarm, + setIsAlarm, + isLetter, + setIsLetter, + isFeedback, + setIsFeedback, + isKeyword, + setIsKeyword, + } = useContext(UseStateContext); + + const onClickAlarm = () => { + setIsAlarm((preState) => !preState); + if (isLetter === true) { + setIsLetter((preState) => !preState); + } else if (setting === true) { + setSetting((preState) => !preState); + } else if (isFeedback === true) { + setIsFeedback((preState) => !preState); + } else if (isKeyword === true) { + setIsKeyword((preState) => !preState); + } + }; + + const onClickLetter = () => { + setIsLetter((preState) => !preState); + if (isAlarm === true) { + setIsAlarm((preState) => !preState); + } else if (setting === true) { + setSetting((preState) => !preState); + } else if (isFeedback === true) { + setIsFeedback((preState) => !preState); + } else if (isKeyword === true) { + setIsKeyword((preState) => !preState); + } + }; + + return ( +
+
+ + + { + nav("/", { state: {} }); + }} + src={blackLogo} + style={{ width: "52px" }} + /> +
+
+ ); +}; + +export default HeaderTeam; diff --git a/blip-project/src/components/Page/Src/page/Keyword.jsx b/blip-project/src/components/Page/Src/page/Keyword.jsx new file mode 100644 index 0000000..e090df7 --- /dev/null +++ b/blip-project/src/components/Page/Src/page/Keyword.jsx @@ -0,0 +1,17 @@ +import "../../../CSS/Keyword.css"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; + +const Keyword = () => { + return ( + <> +
+

+ 아직 받은 회의 일정 및 키워드 요약이 없어요 +

+
+ + ); +}; + +export default Keyword; diff --git a/blip-project/src/components/Page/Src/page/LetterTeam.jsx b/blip-project/src/components/Page/Src/page/LetterTeam.jsx new file mode 100644 index 0000000..8f7cce7 --- /dev/null +++ b/blip-project/src/components/Page/Src/page/LetterTeam.jsx @@ -0,0 +1,25 @@ +import "../../../CSS/LetterTeam.css"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; +import { useLocation } from "react-router-dom"; + +const Letter = () => { + const location = useLocation() + return ( + <> +
+

+ 초대장이 없어요 +

+
+ + ); +}; + +export default Letter; diff --git a/blip-project/src/components/Page/Src/page/MeetingContent.jsx b/blip-project/src/components/Page/Src/page/MeetingContent.jsx new file mode 100644 index 0000000..e170034 --- /dev/null +++ b/blip-project/src/components/Page/Src/page/MeetingContent.jsx @@ -0,0 +1,15 @@ +import "../../../CSS/MeetingContent.css" +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; + +const MeetingContent = () => { + return ( +
+
+ 아직 기록된 회의 내용이 없어요 +
+
+ ); +}; + +export default MeetingContent; diff --git a/blip-project/src/components/Page/Src/page/OwnerTeam.jsx b/blip-project/src/components/Page/Src/page/OwnerTeam.jsx new file mode 100644 index 0000000..dc767e5 --- /dev/null +++ b/blip-project/src/components/Page/Src/page/OwnerTeam.jsx @@ -0,0 +1,132 @@ +import "../../../CSS/OwnerTeam.css"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; +import { useRef, useState, useContext, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { TeamDel } from "../../Main/Main"; +import { UseStateContext } from "../../../../Router"; +import { FindId } from "../../Main/Main"; +import ModalDel from "../../Modal/ModalDel"; +import Camera from "../../../../svg/camera.svg"; + +const OwnerTeam = () => { + const fileInputImg = useRef(null); + const [inputFont, setInputFont] = useState(""); + const [isOpenModal, setIsOpenModal] = useState(false); + const { itemContent, itemId, image, setImage } = useContext(TeamDel); + const { targetId, setTargetId, teamImages, setTeamImages } = + useContext(FindId); + const { setSetting } = useContext(UseStateContext); + const nav = useNavigate(); + + const openModal = () => setIsOpenModal(true); + const closeModal = () => setIsOpenModal(false); + + const handleImg = (e) => { + const file = e.target.files[0]; + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => { + setTeamImages((prevState) => ({ + ...prevState, + [targetId]: reader.result, + })); + }; + }; + + const handleImage = () => { + fileInputImg.current.click(); + }; + + const onChnageInput = (e) => { + setInputFont(e.target.value); + }; + + const CreateImg = () => { + if (image || inputFont) { + nav("/", { state: { itemId } }); + setSetting(false); + setTargetId(null); + } + }; + + useEffect(() => { + if (targetId && teamImages[targetId]) { + setImage(teamImages[targetId]); + } + }, [targetId, teamImages]); + + return ( +
+
+
+ 설정 +
+
+
+ 팀 스페이스 이미지 수정 +
+

+ 팀원들에게 보여질 이미지를 설정하세요. +

+
+
+ {targetId === itemId ? ( + Team Space + ) : ( + Click to upload + )} + +
+
+
+ 팀 스페이스 이름 수정 +
+

+ 팀원들에게 보여질 팀스페이스 이름을 설정하세요. +

+
+
+ +
+
+
+ {image || inputFont ? ( + + ) : ( + + )} + +
+ {isOpenModal && } +
+ ); +}; + +export default OwnerTeam; diff --git a/blip-project/src/components/Page/Src/page/StartTeamJoinNo.jsx b/blip-project/src/components/Page/Src/page/StartTeamJoinNo.jsx new file mode 100644 index 0000000..4c07397 --- /dev/null +++ b/blip-project/src/components/Page/Src/page/StartTeamJoinNo.jsx @@ -0,0 +1,129 @@ +import "../../../CSS/StartTeamJoinNo.css"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; +import Modal from "../../Modal/Modal"; +import { useState, useContext, useRef } from "react"; +import { useNavigate } from "react-router-dom"; +import { SidebarContext } from "../../../../Router"; +import axios from "axios"; + +const StartTeamJoinNo = () => { + const [isModalOpen, setIsModalOpen] = useState(false); + const [urlInput, setUrlInput] = useState(""); + const [isUrl, setIsUrl] = useState(false); + const { dispatch } = useContext(SidebarContext); + const [content, setContent] = useState(""); + const submitRef = useRef(); + + const apiUrl = import.meta.env.VITE_API_URL_URL_JOIN; + + const joinTeam = async (TeamId) => { + const url = `${apiUrl}/data`; + const accessToken = "토큰 값"; + + const data = { + item_id: "fagda", + }; + try { + const reponse = await axios.post(url, data, { + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + }); + console.log("팀 가입 성공", reponse.data); + return reponse.data; + } catch (error) { + console.log("팀 가입 실패", error); + alert("팀 참가에 실패했습니다. 다시 시도해주세요"); + } + }; + + const onClickUrl = async () => { + if (isUrl) { + const teamId = new URL(urlInput).searchParams.get("team_id"); + + if (teamId) { + const result = await joinTeam(teamId); + + if (result) { + nav("/", { state: { urlInput } }); + dispatch.onCreatedouble(content); + setContent(""); + } else { + openModal(); + } + } else { + alert("유효하지 않은 초대 링크입니다. 다시 확인해주세여. "); + } + } else if (content === "") { + submitRef.current.focus(); + return; + } + }; + + const onChangeUrlInput = (e) => { + const urlValue = e.target.value; + setUrlInput(urlValue); + try { + new URL(urlValue); + setIsUrl(true); + } catch (error) { + setIsUrl(false); + } + }; + + const nav = useNavigate(); + + const handleKeyDown = (e) => { + if (e.key === "Enter") { + onClickUrl(); + } + }; + + const openModal = () => setIsModalOpen(true); + const closeModal = () => setIsModalOpen(false); + + return ( + <> +
+
+
+
+

팀을 꾸리거나 팀에 참여하세요!

+

초대받은 팀의 코드를 입력하세요!

+
+ +
+ +
+
+ {isModalOpen && } + + ); +}; + +export default StartTeamJoinNo; diff --git a/blip-project/src/components/Page/Src/page/UserStart.jsx b/blip-project/src/components/Page/Src/page/UserStart.jsx new file mode 100644 index 0000000..4453b1a --- /dev/null +++ b/blip-project/src/components/Page/Src/page/UserStart.jsx @@ -0,0 +1,113 @@ +import "../../../CSS/UserStart.css"; +import { typography } from "../../../../fonts/fonts"; +import { color } from "../../../../style/color"; +import FeedbackSvg from "../../../../svg/feedback.svg"; +import { useContext } from "react"; +import { UseStateContext } from "../../../../Router"; +import Feedback from "./Feedback"; +import Keyword from "./Keyword"; +import Graph from "../function/graph"; + +const UserStart = () => { + + const { + setting, + setSetting, + isAlarm, + setIsAlarm, + isLetter, + setIsLetter, + isFeedback, + setIsFeedback, + isKeyword, + setIsKeyword, + } = useContext(UseStateContext); + + const onClickFeedback = () => { + setIsFeedback((preState) => !preState); + if (isLetter === true) { + setIsLetter((preState) => !preState); + } else if (setting === true) { + setSetting((preState) => !preState); + } else if (isAlarm === true) { + setIsAlarm((preState) => !preState); + } else if (isKeyword === true) { + setIsKeyword((preState) => !preState); + } + }; + + const onClickKeyword = () => { + setIsKeyword((preState) => !preState); + if (isLetter === true) { + setIsLetter((preState) => !preState); + } else if (setting === true) { + setSetting((preState) => !preState); + } else if (isAlarm === true) { + setIsAlarm((preState) => !preState); + } else if (isFeedback === true) { + setIsFeedback((preState) => !preState); + } + }; + + return ( + <> + {isFeedback ? ( + + ) : isKeyword ? ( + + ) : ( +
+
+
+
+ 키워드 요약 확인하기 +
+

+ 진행한 회의를 바탕으로 키워드를 요약했어요! +

+ +
+
+
+
+
+
회의 피드백 확인하기
+

+ 진행한 회의를 피드백 해드릴게요! +

+
+ +
+ +
+ +
+ )} + + ); +}; + +export default UserStart; diff --git a/blip-project/src/components/Page/Src/sidebarTeam.jsx b/blip-project/src/components/Page/Src/sidebarTeam.jsx new file mode 100644 index 0000000..6844b16 --- /dev/null +++ b/blip-project/src/components/Page/Src/sidebarTeam.jsx @@ -0,0 +1,138 @@ +import "../../CSS/sidebarTeam.css"; +import { typography } from "../../../fonts/fonts"; +import { color } from "../../../style/color"; +import { useContext, useEffect } from "react"; +import { SidebarContext } from "../../../Router"; +import { UseStateContext } from "../../../Router"; +import { TeamDel } from "../Main/Main"; +import { FindId } from "../Main/Main"; +import { useNavigate } from "react-router-dom"; + +const SidebarTeam = () => { + const nav = useNavigate(); + const { todos } = useContext(SidebarContext); + const { image, setImage, itemId, Owner, setOwner, join, setJoin } = + useContext(TeamDel); + const { basic, setBasic, discord } = useContext(UseStateContext); + + const { + setting, + setSetting, + isAlarm, + setIsAlarm, + isLetter, + setIsLetter, + isFeedback, + setIsFeedback, + isKeyword, + setIsKeyword, + } = useContext(UseStateContext); + + const { targetId, setTargetId, teamImages, setTeamImages } = + useContext(FindId); + console.log("tlqkf", targetId); + + const onClickEffect = (item) => { + if (item.isPlus) { + if (basic) { + setBasic((prev) => !prev); + } + if (join) { + setJoin((preState) => !preState); + } + nav("/", { + state: { + itemContent: + typeof item.content === "string" ? item.content : "기본 텍스트", + itemId: item.id, + }, + }); + } else { + if (item.id % 2 === 0) { + if (Owner) { + setOwner((preState) => !preState); + } + if (!basic) { + setBasic((prev) => !prev); + } + if (join) { + setJoin((preState) => !preState); + } + console.log(targetId); + } else { + if (!join) { + setJoin((preState) => !preState); + } + if (!basic) { + setBasic((prev) => !prev); + } + if (Owner) { + setOwner((preState) => !preState); + } + } + nav("/", { + state: { + itemContent: + typeof item.content === "string" ? item.content : "기본 텍스트", + itemId: item.id, + }, + }); + } + + if (isLetter) setIsLetter(false); + if (setting) setSetting(false); + if (isAlarm) setIsAlarm(false); + if (isKeyword) setIsKeyword(false); + if (isFeedback) setIsFeedback(false); + }; + + return ( + <> +
+ {todos.length > 0 ? ( + todos.map((item) => ( +
onClickEffect(item)} + style={{ + ...typography.Header2, + backgroundColor: item.isPlus + ? "transparent" + : color.GrayScale[1], + }} + > + + {item.isPlus ? ( + item.content + ) : item.id === targetId && teamImages[targetId] ? ( + Team Space + ) : ( + item.content + )} + +
+ )) + ) : ( +

기본값이 없다

+ )} +
+ + ); +}; + +export default SidebarTeam; diff --git a/blip-project/src/components/SignUpLogin/email.jsx b/blip-project/src/components/SignUpLogin/email.jsx new file mode 100644 index 0000000..d4366dc --- /dev/null +++ b/blip-project/src/components/SignUpLogin/email.jsx @@ -0,0 +1,15 @@ +import Input from "./input"; + +export const Email = ({ value, onChange, placeholder, ...props }) => { + return ( + + ); +}; + +export default Email; diff --git a/blip-project/src/components/SignUpLogin/id.jsx b/blip-project/src/components/SignUpLogin/id.jsx new file mode 100644 index 0000000..2bf3b2f --- /dev/null +++ b/blip-project/src/components/SignUpLogin/id.jsx @@ -0,0 +1,42 @@ +import Input from "./input"; +import X from "../../svg/X.svg"; +import styled from "styled-components"; + +export const Id = ({ value, onChange, placeholder, name }) => { + const handleClear = () => { + onChange({ target: { name: name, value: "" } }); + }; + + return ( + + + {value && ( + + 삭제 + + )} + + ); +}; + +const IdContainer = styled.div` + position: relative; +`; + +const ClearIcon = styled.div` + cursor: pointer; + position: absolute; + right: 15px; + top: 50%; + transform: translateY(-50%); +`; + +export default Id; diff --git a/blip-project/src/components/SignUpLogin/input.jsx b/blip-project/src/components/SignUpLogin/input.jsx new file mode 100644 index 0000000..0313380 --- /dev/null +++ b/blip-project/src/components/SignUpLogin/input.jsx @@ -0,0 +1,27 @@ +import React, { forwardRef } from "react"; +import styled from "styled-components"; +import { color } from "../../style/color"; + +const StyledInput = styled.input` + width: ${(props) => props.width || "400px"}; + height: ${(props) => props.height || "38px"}; + border-radius: ${(props) => props.borderRadius || "12px"}; + border: 2px solid; + border-color: ${(props) => props.borderColor || color.GrayScale[2]}; + background-image: ${(props) => props.backgroundImage || "none"}; + background-repeat: no-repeat; + background-size: 30px 25px, 24px 24px; + background-position: 20px center, calc(100% - 20px) center; + margin: ${(props) => props.margin || "0"}; + text-indent: ${(props) => props.margin || "15px"}; + flex-wrap: wrap; + input { + min-width: 64px; + } +`; + +const Input = forwardRef((props, ref) => { + return ; +}); + +export default Input; diff --git a/blip-project/src/components/SignUpLogin/number.jsx b/blip-project/src/components/SignUpLogin/number.jsx new file mode 100644 index 0000000..e7297ca --- /dev/null +++ b/blip-project/src/components/SignUpLogin/number.jsx @@ -0,0 +1,54 @@ +import { useState } from "react"; +import styled from "styled-components"; +import Input from "./input"; +import colorCheck from "../../svg/colorCheck.png"; + +export const NumberInput = ({ + value, + onChange, + placeholder, + isVerified, + ...props +}) => { + return ( + + + + {isVerified && ( + + 인증 성공 + + )} + + + ); +}; + +const NumberAll = styled.div``; + +const FakeNumberDiv = styled.div` + position: relative; +`; + +const VerifiedIcon = styled.div` + position: absolute; + right: 15px; + top: 50%; + transform: translateY(-50%); +`; + +export default NumberInput; diff --git a/blip-project/src/components/SignUpLogin/onValidMail.jsx b/blip-project/src/components/SignUpLogin/onValidMail.jsx new file mode 100644 index 0000000..0f5e555 --- /dev/null +++ b/blip-project/src/components/SignUpLogin/onValidMail.jsx @@ -0,0 +1,23 @@ +const onValidMail = useCallback( + (e) => { + e.preventDefault(); + fetch(api.emailCheck, { + method: "POST", + headers: { "Content-Type": "application/json;charset=utf-8" }, + body: JSON.stringify({ + userEmail: formValue.email, + }), + }).then((res) => { + if (res.status === 200) { + setIsGetCode(true); + setIsTimer(true); + setCount(180); + } else if (res.status === 401) { + alert("이미 존재하는 이메일입니다."); + } else if (res.status === 402) { + alert("이미 인증이 진행중입니다."); + } + }); + }, + [formValue] +); diff --git a/blip-project/src/components/SignUpLogin/password.jsx b/blip-project/src/components/SignUpLogin/password.jsx new file mode 100644 index 0000000..e28f5b5 --- /dev/null +++ b/blip-project/src/components/SignUpLogin/password.jsx @@ -0,0 +1,52 @@ +import { useState } from "react"; +import styled from "styled-components"; +import Input from "./input"; +import eyeOpen from "../../svg/eyeOpen.svg"; +import eyeOff from "../../svg/eyeOff.svg"; + +export const PassWord = ({ + value, + onChange, + showEye = "none", + placeholder, + ...props +}) => { + const [showPswd, setShowPswd] = useState(false); + + const toggleShowPswd = () => { + setShowPswd((prev) => !prev); + }; + + return ( + + + + {value && showEye === "visible" && ( + + 비밀번호 보기 + + )} + + + ); +}; +const PassWordAll = styled.div``; + +const FakePassWordDiv = styled.div` + position: relative; +`; + +const PassWordEyes = styled.div` + cursor: pointer; + position: absolute; + right: 15px; + top: 50%; + transform: translateY(-50%); +`; diff --git a/blip-project/src/components/SignUpLogin/passwordCheck.jsx b/blip-project/src/components/SignUpLogin/passwordCheck.jsx new file mode 100644 index 0000000..a226e05 --- /dev/null +++ b/blip-project/src/components/SignUpLogin/passwordCheck.jsx @@ -0,0 +1,61 @@ +import { useState } from "react"; +import styled from "styled-components"; +import Input from "./input"; +import eyeOpen from "../../svg/eyeOpen.svg"; +import eyeOff from "../../svg/eyeOff.svg"; + +export const PasswordCheck = ({ + value, + onChange, + showEye = "none", + placeholder, + ...props +}) => { + const [showPswd, setShowPswd] = useState(false); + + const toggleShowPswd = () => { + setShowPswd((prev) => !prev); + }; + + return ( + + + + {value && showEye === "visible" && ( + + 눈 아이콘 + + )} + + + ); +}; + +const PassWordAll = styled.div` + position: relative; +`; + +const FakePassWordDiv = styled.div` + position: relative; +`; + +const PassWordEyes = styled.div` + cursor: pointer; + position: absolute; + right: 15px; + top: 50%; + transform: translateY(-50%); +`; + +const ErrorText = styled.p` + color: red; + font-size: 12px; + margin-top: 5px; +`; diff --git a/blip-project/src/components/SignUpLogin/timer.jsx b/blip-project/src/components/SignUpLogin/timer.jsx new file mode 100644 index 0000000..2b9e781 --- /dev/null +++ b/blip-project/src/components/SignUpLogin/timer.jsx @@ -0,0 +1,27 @@ +import { color } from "../../style/color"; +import { typography } from "../../fonts/fonts"; + +const Timer = ({ count }) => { + const formatTime = (time) => { + const minutes = Math.floor(time / 60); + const seconds = time % 60; + return `${minutes}:${seconds < 10 ? `0${seconds}` : seconds}`; + }; + + return ( +
+ {count > 0 ? `${formatTime(count)}` : "시간 초과"} +
+ ); +}; + +export default Timer; diff --git a/blip-project/src/components/TeamJoinNo/HeaderTeamJoinNo.jsx b/blip-project/src/components/TeamJoinNo/HeaderTeamJoinNo.jsx deleted file mode 100644 index f3c1c9e..0000000 --- a/blip-project/src/components/TeamJoinNo/HeaderTeamJoinNo.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import "./HeaderTeamJoinNo.css"; -import Alarm from "/src/svg/Alarm.svg"; -import blackLogo from "/src/svg/blackLogo.svg"; -import Letter from "/src/svg/letter.svg"; - -const HeaderTeamJoinNo = () => { - return ( -
-
- - - -
-
- ); -}; - -export default HeaderTeamJoinNo; diff --git a/blip-project/src/components/TeamJoinNo/MainTeamJoinNo.jsx b/blip-project/src/components/TeamJoinNo/MainTeamJoinNo.jsx deleted file mode 100644 index 186f98c..0000000 --- a/blip-project/src/components/TeamJoinNo/MainTeamJoinNo.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import "./MainTeamJoinNo.css"; -import DateTeamJoinNo from "../DateTeamJoin"; -import HeaderTeamJoinNo from "./HeaderTeamJoinNo"; -import SidebarTeamJoinNo from "./sidebarTeamJoinNo"; -import StartTeamJoinNo from "./StartTeamJoinNo"; -import MeetingTeamJoinNo from "./MeetingTeamJoinNo"; - -const MTeamJoinNo = () => { - return ( - <> - -
- - -
- - -
-
- - ); -}; - -export default MTeamJoinNo; diff --git a/blip-project/src/components/TeamJoinNo/MeetingTeamJoinNo.css b/blip-project/src/components/TeamJoinNo/MeetingTeamJoinNo.css deleted file mode 100644 index 07fa06f..0000000 --- a/blip-project/src/components/TeamJoinNo/MeetingTeamJoinNo.css +++ /dev/null @@ -1,33 +0,0 @@ -.MeetingTeamJoinNos { - width: 100%; - height: 38%; - border-radius: 12px; - color: var(--black); - background-color: var(--gray-50); -} - -.MeetingTJoinNoFont { - padding: 10px; -} - -.MMeetingTJoinNo { - width: 100%; - height: 80%; - display: flex; - justify-content: center; -} - -.MeetingTJoinNo { - display: flex; - align-items: center; - justify-content: center; - color: var(--gray-400); -} - -.MeetingTJoinNoButton { - width: 100%; - height: 20%; - border-radius: 12px; - color: var(--gray-400); - border: none; -} diff --git a/blip-project/src/components/TeamJoinNo/MeetingTeamJoinNo.jsx b/blip-project/src/components/TeamJoinNo/MeetingTeamJoinNo.jsx deleted file mode 100644 index e7707e7..0000000 --- a/blip-project/src/components/TeamJoinNo/MeetingTeamJoinNo.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import "./MeetingTeamJoinNo.css"; -import { color } from "../../style/color"; -import { typography } from "../../fonts/fonts"; - -const MeetingTeamJoinNo = () => { - return ( - <> -
-
- 지난 회의 내용 요약 -
-
-
- 아직 기록된 회의 내용이 없어요 -
-
-
- - - ); -}; - -export default MeetingTeamJoinNo; diff --git a/blip-project/src/components/TeamJoinNo/Popup.jsx b/blip-project/src/components/TeamJoinNo/Popup.jsx deleted file mode 100644 index 0e89446..0000000 --- a/blip-project/src/components/TeamJoinNo/Popup.jsx +++ /dev/null @@ -1,5 +0,0 @@ -const Popup = () =>{ - return
Popup
-} - -export default Popup; \ No newline at end of file diff --git a/blip-project/src/components/TeamJoinNo/StartTeamJoinNo.jsx b/blip-project/src/components/TeamJoinNo/StartTeamJoinNo.jsx deleted file mode 100644 index b18baf4..0000000 --- a/blip-project/src/components/TeamJoinNo/StartTeamJoinNo.jsx +++ /dev/null @@ -1,49 +0,0 @@ -import "./StartTeamJoinNo.css"; -import Popup from "./Popup"; -import { typography } from "../../fonts/fonts"; -import { color } from "../../style/color"; - -const StartTeamJoinNo = () => { - const onClickPopup = () =>{ - window.open( - "Popup.jsx", - "new", - "width = 70%, height=300, top = 100, left = 100" - ); - } - return ( - <> -
-
-
-
-

팀을 꾸리거나 팀에 참여하세요!

-

초대받은 팀의 코드를 입력하세요!

-
- -
- -
-
- - ); -}; - -export default StartTeamJoinNo; diff --git a/blip-project/src/components/TeamJoinNo/sidebarTeamJoinNo.css b/blip-project/src/components/TeamJoinNo/sidebarTeamJoinNo.css deleted file mode 100644 index 14f8cd0..0000000 --- a/blip-project/src/components/TeamJoinNo/sidebarTeamJoinNo.css +++ /dev/null @@ -1,8 +0,0 @@ -.MainSTJoinNo { - height: 100%; - width: 4%; - display: flex; - flex-direction: column; - align-items: center; - padding-left: 20px; -} \ No newline at end of file diff --git a/blip-project/src/components/TeamJoinNo/sidebarTeamJoinNo.jsx b/blip-project/src/components/TeamJoinNo/sidebarTeamJoinNo.jsx deleted file mode 100644 index 1a424db..0000000 --- a/blip-project/src/components/TeamJoinNo/sidebarTeamJoinNo.jsx +++ /dev/null @@ -1,12 +0,0 @@ -import "./SidebarTeamJoinNo.css"; -import Add from "/src/svg/add.svg"; - -const SidebarTeamJoinNo = () => { - return ( -
- -
- ); -}; - -export default SidebarTeamJoinNo; \ No newline at end of file diff --git a/blip-project/src/index.css b/blip-project/src/index.css index 6119ad9..e69de29 100644 --- a/blip-project/src/index.css +++ b/blip-project/src/index.css @@ -1,68 +0,0 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/blip-project/src/style/color.jsx b/blip-project/src/style/color.jsx index 42991cf..e610dc7 100644 --- a/blip-project/src/style/color.jsx +++ b/blip-project/src/style/color.jsx @@ -26,7 +26,7 @@ export const color = { "#B5B5B5", // Gray 300 "#A1A1A1", // Gray 400 "#8C8C8C", // Gray 500 - "#610064", // Gray 600 + "#616064", // Gray 600 "#4C4B4F", // Gray 700 "#38373B", // Gray 800 ], diff --git a/blip-project/src/svg/DisAlarm.svg b/blip-project/src/svg/DisAlarm.svg new file mode 100644 index 0000000..42fcfba --- /dev/null +++ b/blip-project/src/svg/DisAlarm.svg @@ -0,0 +1,3 @@ + + + diff --git a/blip-project/src/svg/DisCamera.svg b/blip-project/src/svg/DisCamera.svg new file mode 100644 index 0000000..3da1df9 --- /dev/null +++ b/blip-project/src/svg/DisCamera.svg @@ -0,0 +1,4 @@ + + + + diff --git a/blip-project/src/svg/ESC.svg b/blip-project/src/svg/ESC.svg new file mode 100644 index 0000000..20806c4 --- /dev/null +++ b/blip-project/src/svg/ESC.svg @@ -0,0 +1,4 @@ + + + + diff --git a/blip-project/src/svg/Exit.svg b/blip-project/src/svg/Exit.svg new file mode 100644 index 0000000..f217d0d --- /dev/null +++ b/blip-project/src/svg/Exit.svg @@ -0,0 +1,3 @@ + + + diff --git a/blip-project/src/svg/FullScreen.svg b/blip-project/src/svg/FullScreen.svg new file mode 100644 index 0000000..12f4d9a --- /dev/null +++ b/blip-project/src/svg/FullScreen.svg @@ -0,0 +1,3 @@ + + + diff --git a/blip-project/src/svg/Graph.svg b/blip-project/src/svg/Graph.svg new file mode 100644 index 0000000..3b9d5e0 --- /dev/null +++ b/blip-project/src/svg/Graph.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blip-project/src/svg/MettingStart.svg b/blip-project/src/svg/MettingStart.svg new file mode 100644 index 0000000..a496b21 --- /dev/null +++ b/blip-project/src/svg/MettingStart.svg @@ -0,0 +1,3 @@ + + + diff --git a/blip-project/src/svg/MettingStop.svg b/blip-project/src/svg/MettingStop.svg new file mode 100644 index 0000000..a95ad0c --- /dev/null +++ b/blip-project/src/svg/MettingStop.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/blip-project/src/svg/Mike.svg b/blip-project/src/svg/Mike.svg new file mode 100644 index 0000000..744455c --- /dev/null +++ b/blip-project/src/svg/Mike.svg @@ -0,0 +1,4 @@ + + + + diff --git a/blip-project/src/svg/NoCamera.svg b/blip-project/src/svg/NoCamera.svg new file mode 100644 index 0000000..2637b67 --- /dev/null +++ b/blip-project/src/svg/NoCamera.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/blip-project/src/svg/NoMike.svg b/blip-project/src/svg/NoMike.svg new file mode 100644 index 0000000..db8d076 --- /dev/null +++ b/blip-project/src/svg/NoMike.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/blip-project/src/svg/X.svg b/blip-project/src/svg/X.svg new file mode 100644 index 0000000..c088b37 --- /dev/null +++ b/blip-project/src/svg/X.svg @@ -0,0 +1,3 @@ + + + diff --git a/blip-project/src/svg/XFullScreen.svg b/blip-project/src/svg/XFullScreen.svg new file mode 100644 index 0000000..5abfbdc --- /dev/null +++ b/blip-project/src/svg/XFullScreen.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/blip-project/src/svg/camera.svg b/blip-project/src/svg/camera.svg new file mode 100644 index 0000000..1345ba5 --- /dev/null +++ b/blip-project/src/svg/camera.svg @@ -0,0 +1,4 @@ + + + + diff --git a/blip-project/src/svg/council.svg b/blip-project/src/svg/council.svg new file mode 100644 index 0000000..8185c8b --- /dev/null +++ b/blip-project/src/svg/council.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/blip-project/src/svg/eyeOff.svg b/blip-project/src/svg/eyeOff.svg new file mode 100644 index 0000000..7d3b5cf --- /dev/null +++ b/blip-project/src/svg/eyeOff.svg @@ -0,0 +1,3 @@ + + + diff --git a/blip-project/src/svg/eyeOpen.svg b/blip-project/src/svg/eyeOpen.svg new file mode 100644 index 0000000..1d42405 --- /dev/null +++ b/blip-project/src/svg/eyeOpen.svg @@ -0,0 +1,3 @@ + + + diff --git a/blip-project/src/svg/feedback.svg b/blip-project/src/svg/feedback.svg new file mode 100644 index 0000000..a0d6b1f --- /dev/null +++ b/blip-project/src/svg/feedback.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/blip-project/src/svg/member.svg b/blip-project/src/svg/member.svg new file mode 100644 index 0000000..80d1a82 --- /dev/null +++ b/blip-project/src/svg/member.svg @@ -0,0 +1,4 @@ + + + + diff --git a/blip-project/src/svg/plus.svg b/blip-project/src/svg/plus.svg new file mode 100644 index 0000000..73996dd --- /dev/null +++ b/blip-project/src/svg/plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/blip-project/src/svg/profileDefault.svg b/blip-project/src/svg/profileDefault.svg new file mode 100644 index 0000000..4fc132b --- /dev/null +++ b/blip-project/src/svg/profileDefault.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/blip-project/src/svg/setting.svg b/blip-project/src/svg/setting.svg new file mode 100644 index 0000000..ecf6fdc --- /dev/null +++ b/blip-project/src/svg/setting.svg @@ -0,0 +1,3 @@ + + + diff --git a/blip-project/vite.config.js b/blip-project/vite.config.js index 8b0f57b..a9f1fd7 100644 --- a/blip-project/vite.config.js +++ b/blip-project/vite.config.js @@ -1,7 +1,22 @@ -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; -// https://vite.dev/config/ export default defineConfig({ + root: "./", // root를 현재 디렉토리로 설정 + base: "/", // 배포 시의 기본 URL을 프로젝트의 루트로 설정 plugins: [react()], -}) + server: { + open: true, // 서버 시작 시 브라우저 자동 열기 + port: 5173, // 기본 포트 설정 + proxy: { + "/jitsi-api": { + target: "https://your-jitsi-server.com", + changeOrigin: true, + rewrite: (path) => path.replace(/^\/jitsi-api/, ""), + }, + }, + }, + build: { + chunkSizeWarningLimit: 1500, // 번들 크기 경고 크기 설정 + }, +});