mirror of
https://github.com/LucasVbr/meeting-app.git
synced 2026-05-13 17:21:53 +00:00
Send messages with sockets ❤️
Took 3 hours 51 minutes
This commit is contained in:
Generated
+250
-3
@@ -13,6 +13,7 @@
|
||||
"@emotion/styled": "^11.10.6",
|
||||
"@premieroctet/next-crud": "^2.2.0",
|
||||
"@prisma/client": "^4.11.0",
|
||||
"@reduxjs/toolkit": "^1.9.3",
|
||||
"@types/react": "18.0.28",
|
||||
"@types/react-dom": "18.0.11",
|
||||
"bcrypt": "^5.1.0",
|
||||
@@ -27,7 +28,9 @@
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hook-form": "^7.43.5",
|
||||
"react-icons": "^4.8.0"
|
||||
"react-icons": "^4.8.0",
|
||||
"socket.io": "^4.6.1",
|
||||
"socket.io-client": "^4.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
@@ -2129,11 +2132,39 @@
|
||||
"integrity": "sha512-KV+IrVh8LdwBfJjDGdbZZDg+KwQ6b4Ee7/hLiTpL8ZHLI2IdGOufRxvmZSTuio28wfAporSA+N0YdzAdx43gWA==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@reduxjs/toolkit": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.3.tgz",
|
||||
"integrity": "sha512-GU2TNBQVofL09VGmuSioNPQIu6Ml0YLf4EJhgj0AvBadRlCGzUWet8372LjvO4fqKZF2vH1xU0htAa7BrK9pZg==",
|
||||
"dependencies": {
|
||||
"immer": "^9.0.16",
|
||||
"redux": "^4.2.0",
|
||||
"redux-thunk": "^2.4.2",
|
||||
"reselect": "^4.1.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.9.0 || ^17.0.0 || ^18",
|
||||
"react-redux": "^7.2.1 || ^8.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-redux": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rushstack/eslint-patch": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
|
||||
"integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg=="
|
||||
},
|
||||
"node_modules/@socket.io/component-emitter": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
|
||||
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz",
|
||||
@@ -2184,6 +2215,19 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
|
||||
},
|
||||
"node_modules/@types/cors": {
|
||||
"version": "2.8.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
|
||||
"integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cross-spawn": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz",
|
||||
@@ -2229,8 +2273,7 @@
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.15.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.1.tgz",
|
||||
"integrity": "sha512-U2TWca8AeHSmbpi314QBESRk7oPjSZjDsR+c+H4ECC1l+kFgpZf8Ydhv3SJpPy51VyZHHqxlb6mTTqYNNRVAIw==",
|
||||
"devOptional": true
|
||||
"integrity": "sha512-U2TWca8AeHSmbpi314QBESRk7oPjSZjDsR+c+H4ECC1l+kFgpZf8Ydhv3SJpPy51VyZHHqxlb6mTTqYNNRVAIw=="
|
||||
},
|
||||
"node_modules/@types/normalize-package-data": {
|
||||
"version": "2.4.1",
|
||||
@@ -2388,6 +2431,18 @@
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.34",
|
||||
"negotiator": "0.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.8.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
|
||||
@@ -2794,6 +2849,14 @@
|
||||
],
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/base64id": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
|
||||
"engines": {
|
||||
"node": "^4.5.0 || >= 5.9"
|
||||
}
|
||||
},
|
||||
"node_modules/bcrypt": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz",
|
||||
@@ -3154,6 +3217,18 @@
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/cors": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||
"dependencies": {
|
||||
"object-assign": "^4",
|
||||
"vary": "^1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/cosmiconfig": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
|
||||
@@ -3434,6 +3509,54 @@
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io": {
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz",
|
||||
"integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==",
|
||||
"dependencies": {
|
||||
"@types/cookie": "^0.4.1",
|
||||
"@types/cors": "^2.8.12",
|
||||
"@types/node": ">=10.0.0",
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "2.0.0",
|
||||
"cookie": "~0.4.1",
|
||||
"cors": "~2.8.5",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~5.0.3",
|
||||
"ws": "~8.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io-client": {
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.4.0.tgz",
|
||||
"integrity": "sha512-GyKPDyoEha+XZ7iEqam49vz6auPnNJ9ZBfy89f+rMMas8AuiMWOZ9PVzu8xb9ZC6rafUqiGHSCfu22ih66E+1g==",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~5.0.3",
|
||||
"ws": "~8.11.0",
|
||||
"xmlhttprequest-ssl": "~2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io-parser": {
|
||||
"version": "5.0.6",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz",
|
||||
"integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io/node_modules/cookie": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.12.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
|
||||
@@ -4815,6 +4938,15 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/immer": {
|
||||
"version": "9.0.21",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
|
||||
"integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/immer"
|
||||
}
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
@@ -5704,6 +5836,14 @@
|
||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/new-github-issue-url": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/new-github-issue-url/-/new-github-issue-url-0.2.1.tgz",
|
||||
@@ -6903,6 +7043,22 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/redux": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.9.2"
|
||||
}
|
||||
},
|
||||
"node_modules/redux-thunk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
|
||||
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
|
||||
"peerDependencies": {
|
||||
"redux": "^4"
|
||||
}
|
||||
},
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.13.11",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
||||
@@ -6947,6 +7103,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/reselect": {
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
|
||||
"integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A=="
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
|
||||
@@ -7162,6 +7323,56 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz",
|
||||
"integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "~2.0.0",
|
||||
"debug": "~4.3.2",
|
||||
"engine.io": "~6.4.1",
|
||||
"socket.io-adapter": "~2.5.2",
|
||||
"socket.io-parser": "~4.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io-adapter": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz",
|
||||
"integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==",
|
||||
"dependencies": {
|
||||
"ws": "~8.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io-client": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.6.1.tgz",
|
||||
"integrity": "sha512-5UswCV6hpaRsNg5kkEHVcbBIXEYoVbMQaHJBXJCyEQ+CiFPV1NIOY0XOFWG4XR4GZcB8Kn6AsRs/9cy9TbqVMQ==",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.2",
|
||||
"engine.io-client": "~6.4.0",
|
||||
"socket.io-parser": "~4.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io-parser": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz",
|
||||
"integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
@@ -7875,6 +8086,14 @@
|
||||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/wcwidth": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
|
||||
@@ -7981,6 +8200,34 @@
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.11.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
|
||||
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/xmlhttprequest-ssl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
|
||||
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
|
||||
+4
-1
@@ -14,6 +14,7 @@
|
||||
"@emotion/styled": "^11.10.6",
|
||||
"@premieroctet/next-crud": "^2.2.0",
|
||||
"@prisma/client": "^4.11.0",
|
||||
"@reduxjs/toolkit": "^1.9.3",
|
||||
"@types/react": "18.0.28",
|
||||
"@types/react-dom": "18.0.11",
|
||||
"bcrypt": "^5.1.0",
|
||||
@@ -28,7 +29,9 @@
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hook-form": "^7.43.5",
|
||||
"react-icons": "^4.8.0"
|
||||
"react-icons": "^4.8.0",
|
||||
"socket.io": "^4.6.1",
|
||||
"socket.io-client": "^4.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -1,204 +0,0 @@
|
||||
import {
|
||||
Button,
|
||||
Flex,
|
||||
Grid,
|
||||
GridItem,
|
||||
Image,
|
||||
Input,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
useDisclosure,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import { useState } from "react";
|
||||
import { RiEditBoxLine } from "react-icons/ri";
|
||||
|
||||
export default function ModalModifyImages(props) {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const { images, user, userData, setUserData } = props;
|
||||
const [listImage, setlistImage] = useState(images);
|
||||
const toast = useToast();
|
||||
|
||||
const uploadImage = async (file) => {
|
||||
const body = new FormData();
|
||||
body.append("file", file);
|
||||
const imagePostOptions = {
|
||||
method: "POST",
|
||||
body,
|
||||
};
|
||||
|
||||
const imagePatchOptions = {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
images: [...listImage, `imageUsers/${file.name}`],
|
||||
}),
|
||||
};
|
||||
|
||||
fetch(`/api/file/uploadFile`, imagePostOptions)
|
||||
.then((res) => {
|
||||
fetch(`/api/users/${user.id}`, imagePatchOptions)
|
||||
.then((res) => {
|
||||
toast({
|
||||
title: `Ajout d'image effectué`,
|
||||
status: "success",
|
||||
isClosable: true,
|
||||
});
|
||||
setlistImage([...listImage, `imageUsers/${file.name}`]);
|
||||
// router.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
setIsLoading(false);
|
||||
toast({
|
||||
title: `Erreur lors de l'ajout des images`,
|
||||
status: "error",
|
||||
isClosable: true,
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
toast({
|
||||
title: `Erreur lors de l'ajout des images`,
|
||||
status: "error",
|
||||
isClosable: true,
|
||||
});
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
const deleteImage = async (fileName) => {
|
||||
let newListImage = listImage;
|
||||
const index = newListImage.indexOf(fileName);
|
||||
|
||||
if (index > -1) {
|
||||
newListImage.splice(index, 1);
|
||||
setlistImage([...newListImage]);
|
||||
}
|
||||
|
||||
const imageDeleteOptions = {
|
||||
method: "DELETE",
|
||||
body: JSON.stringify({ fileName: fileName.split("/").pop() }),
|
||||
};
|
||||
|
||||
fetch(`/api/file/deleteFile`, imageDeleteOptions).then((res) => {
|
||||
const imagePatchOptions = {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
images: [...listImage],
|
||||
}),
|
||||
};
|
||||
fetch(`/api/users/${user.id}`, imagePatchOptions)
|
||||
.then((res) => {
|
||||
toast({
|
||||
title: `Suppression d'image effectué`,
|
||||
status: "success",
|
||||
isClosable: true,
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
toast({
|
||||
title: `Erreur lors de la suppression des images`,
|
||||
status: "error",
|
||||
isClosable: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
colorScheme={"purple"}
|
||||
onClick={onOpen}
|
||||
leftIcon={<RiEditBoxLine />}
|
||||
>
|
||||
Modifier les images
|
||||
</Button>
|
||||
|
||||
<Modal
|
||||
blockScrollOnMount={false}
|
||||
size={"4xl"}
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
scrollBehavior={"inside"}
|
||||
>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Modification des images</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<Grid
|
||||
templateColumns={`repeat(${listImage.length + 1}, 1fr)`}
|
||||
gap={5}
|
||||
>
|
||||
{listImage.map((image, index) => (
|
||||
<GridItem key={index}>
|
||||
<Flex direction={"column"} gap={"1rem"}>
|
||||
<Image src={image} />
|
||||
<Button
|
||||
id={"" + index}
|
||||
colorScheme={"red"}
|
||||
onClick={(e) => {
|
||||
deleteImage(`${listImage[index]}`);
|
||||
}}
|
||||
>
|
||||
Supprimer l'image
|
||||
</Button>
|
||||
</Flex>
|
||||
</GridItem>
|
||||
))}
|
||||
{listImage.length < 5 ? (
|
||||
<GridItem width={"100%"}>
|
||||
<Input
|
||||
type={"file"}
|
||||
height={"100%"}
|
||||
accept={"image/png, image/jpeg, image/webp"}
|
||||
onInput={({ target }) => {
|
||||
const date = new Date();
|
||||
const time = date.getTime();
|
||||
|
||||
const file = target.files[0];
|
||||
const extension = file.name.split(".").pop();
|
||||
const newFile = new File(
|
||||
[file],
|
||||
`${user.id}_${time}.${extension}`,
|
||||
{
|
||||
type: file.type,
|
||||
}
|
||||
);
|
||||
uploadImage(newFile);
|
||||
}}
|
||||
></Input>
|
||||
</GridItem>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Grid>
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button
|
||||
colorScheme="purple"
|
||||
mr={3}
|
||||
onClick={(e) => {
|
||||
setUserData({
|
||||
...userData,
|
||||
images: [...listImage],
|
||||
});
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,27 +1,32 @@
|
||||
import {Button, Flex, Input} from '@chakra-ui/react';
|
||||
import {useState} from 'react';
|
||||
import {User} from '@prisma/client';
|
||||
import {io, Socket} from 'socket.io-client';
|
||||
import Message from '@/components/chat/Message';
|
||||
|
||||
type Props = {
|
||||
user: User,
|
||||
chatId: Props
|
||||
chatId: Props,
|
||||
socket: any
|
||||
}
|
||||
|
||||
export default function FormMessage(props: Props) {
|
||||
const {user, chatId} = props;
|
||||
const {user, socket} = props;
|
||||
const [text, setText] = useState("");
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (text !== "") {
|
||||
fetch("/api/messages", {
|
||||
method: "POST",
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
text,
|
||||
'User': {"connect": {'id': user.id}},
|
||||
'Chat': {"connect": {'id': chatId}}
|
||||
})
|
||||
}).then(res => res.json()).then(res => console.log(res)).catch(err => console.error(err))
|
||||
socket.emit("createdMessage", {text, sender: user.id})
|
||||
|
||||
// fetch("/api/messages", {
|
||||
// method: "POST",
|
||||
// headers: {'Content-Type': 'application/json'},
|
||||
// body: JSON.stringify({
|
||||
// text,
|
||||
// 'User': {"connect": {'id': user.id}},
|
||||
// 'Chat': {"connect": {'id': chatId}}
|
||||
// })
|
||||
// }).then(res => res.json()).then(res => console.log(res)).catch(err => console.error(err))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,11 @@ export default function LeftPanel(props) {
|
||||
const router = useRouter();
|
||||
const { user } = props;
|
||||
|
||||
const formateDate = (dateString) => {
|
||||
var options = { year: "numeric", month: "long", day: "numeric" };
|
||||
return new Date(dateString).toLocaleDateString([], options);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card
|
||||
width={"20vw"}
|
||||
@@ -23,12 +28,17 @@ export default function LeftPanel(props) {
|
||||
<Flex direction={"column"} height={"100%"} margin={"10%"}>
|
||||
<Box>
|
||||
<Image src={user.images[0]} borderRadius={"1rem"} />
|
||||
<Box mt={"1vh"}>
|
||||
<Text fontSize={"1.5rem"} fontWeight={"bold"}>
|
||||
{user.firstName} {user.lastName}
|
||||
</Text>
|
||||
<Text as="i" fontWeight={"bold"}>
|
||||
"{user.aPropos}"
|
||||
<Box mt={"1rem"}>
|
||||
<Flex align={"center"} justifyContent="space-between">
|
||||
<Text fontSize={"1.5rem"} fontWeight={"bold"}>
|
||||
{user.firstName} {user.lastName}
|
||||
</Text>
|
||||
<Text fontSize={"1rem"} fontWeight={"bold"}>
|
||||
{formateDate(user.birthdate)}
|
||||
</Text>
|
||||
</Flex>
|
||||
<Text mt={"3rem"} as="i" fontWeight={"bold"}>
|
||||
"{user.bio}"
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Flex,
|
||||
FormControl,
|
||||
FormErrorMessage,
|
||||
FormLabel,
|
||||
Input,
|
||||
useToast,
|
||||
} from '@chakra-ui/react';
|
||||
import { useSession } from 'next-auth/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
|
||||
export default function settings() {
|
||||
|
||||
const router = useRouter();
|
||||
const toast = useToast();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
register,
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm()
|
||||
|
||||
const [userData, setUserData] = useState({});
|
||||
|
||||
const { data: session, status } = useSession();
|
||||
if (status === "unauthenticated") router.push("/login");
|
||||
|
||||
if (status === "authenticated") {
|
||||
const { user } = session as unknown as Session;
|
||||
|
||||
if (user.role !== "ADMIN") router.push("/login");
|
||||
|
||||
const savePassion = (passion: any) => {
|
||||
const options = {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(passion),
|
||||
};
|
||||
|
||||
fetch(`/api/passions`, options)
|
||||
.then((res) => {
|
||||
setIsLoading(false);
|
||||
toast({
|
||||
position:'top',
|
||||
title: `Passion ajoutée`,
|
||||
status: "success",
|
||||
isClosable: true,
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
setIsLoading(false);
|
||||
toast({
|
||||
title: `Erreur lors de l'ajout`,
|
||||
position :'top',
|
||||
status: "error",
|
||||
isClosable: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box as="form" id='form_passion' width={"80%"} onSubmit={handleSubmit(savePassion)}>
|
||||
<FormControl isInvalid={errors.name}>
|
||||
<FormLabel htmlFor='passion'>Passion</FormLabel>
|
||||
<Input
|
||||
id='passion'
|
||||
placeholder='passion'
|
||||
{...register('name', {
|
||||
required: 'This is required',
|
||||
})}
|
||||
/>
|
||||
<FormErrorMessage>
|
||||
{errors.name && errors.name.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
<Button mt={4} colorScheme='purple' isLoading={isSubmitting} type='submit'>
|
||||
Submit
|
||||
</Button>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import {Server} from 'socket.io';
|
||||
import prismaClient from '@/lib/prismaClient';
|
||||
|
||||
export default async function SocketHandler(req: any, res: any) {
|
||||
const {id: chatId} = req.query;
|
||||
|
||||
// It means that socket server was already initialised
|
||||
if (res.socket.server.io) {
|
||||
console.log('Already set up');
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const io = new Server(res.socket.server);
|
||||
res.socket.server.io = io;
|
||||
|
||||
// Define actions inside
|
||||
io.on('connection', async (socket) => {
|
||||
console.log(socket.id);
|
||||
|
||||
await prismaClient.chat.findFirst({
|
||||
where: {id: chatId},
|
||||
include: {Message: true},
|
||||
}).then(chat => {
|
||||
// @ts-ignore
|
||||
return socket.emit('allOldMessages', chat.Message);
|
||||
});
|
||||
|
||||
socket.on('createdMessage', async (msgInput) => {
|
||||
await prismaClient.message.create({
|
||||
data: {
|
||||
text: msgInput.text,
|
||||
User: {connect: {id: msgInput.sender}},
|
||||
Chat: {connect: {id: chatId}},
|
||||
},
|
||||
}).then((newMessage) => socket.emit('newIncomingMessage', newMessage));
|
||||
});
|
||||
});
|
||||
|
||||
console.log('Setting up socket');
|
||||
res.end();
|
||||
}
|
||||
+48
-11
@@ -1,36 +1,73 @@
|
||||
import {Container, Flex, Input, Text} from '@chakra-ui/react';
|
||||
import {Button, Container, Flex, Input, Text} from '@chakra-ui/react';
|
||||
import Head from 'next/head';
|
||||
import {websiteName} from '@/lib/constants';
|
||||
import {useSession} from 'next-auth/react';
|
||||
import {useRouter} from 'next/router';
|
||||
import {useEffect, useState} from 'react';
|
||||
import {useCallback, useEffect, useState} from 'react';
|
||||
|
||||
import MessageList from '@/components/chat/MessageList';
|
||||
import FormMessage from '@/components/form/FormMessage';
|
||||
|
||||
import {io, Socket} from 'socket.io-client';
|
||||
import {Message} from '@prisma/client';
|
||||
|
||||
export default function ChatId() {
|
||||
const router = useRouter();
|
||||
const {data: session, status} = useSession();
|
||||
const {id} = router.query;
|
||||
const [messages, setMessages] = useState([])
|
||||
const {id: chatId} = router.query;
|
||||
|
||||
const [messages, setMessages] = useState<Message[]>([]);
|
||||
const [text, setText] = useState('');
|
||||
const [socket, setSocket] = useState<Socket>()
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "authenticated")
|
||||
fetch(`/api/messages?where={"ChatID": "${id}"}`)
|
||||
.then(res => res.json())
|
||||
.then(msgs => setMessages(msgs))
|
||||
if (status === 'authenticated') socketInitializer()
|
||||
}, [status]);
|
||||
|
||||
|
||||
const socketInitializer = async () => {
|
||||
await fetch(`/api/socket/chat/${chatId}`)
|
||||
const soc = io()
|
||||
|
||||
soc.on('connect', () => {
|
||||
console.log('connected')
|
||||
})
|
||||
|
||||
soc.on("allOldMessages", (allOldMessages: Message[]) => {
|
||||
console.log("allOldMessages", allOldMessages);
|
||||
setMessages(allOldMessages);
|
||||
})
|
||||
|
||||
soc.on("newIncomingMessage", (newIncomingMessage: Message) => {
|
||||
console.log("newIncomingMessage", newIncomingMessage);
|
||||
console.log("messages", messages);
|
||||
setMessages(messages => ([...messages, newIncomingMessage]));
|
||||
});
|
||||
|
||||
setSocket(soc);
|
||||
}
|
||||
|
||||
if (status === 'loading') return <Text>Loading...</Text>;
|
||||
|
||||
if (session && messages)
|
||||
const handleSubmit = () => {
|
||||
if (text !== "" && socket) {
|
||||
// @ts-ignore
|
||||
socket.emit("createdMessage", {text, sender: session.user.id})
|
||||
setText("");
|
||||
}
|
||||
}
|
||||
|
||||
if (session && session.user && messages)
|
||||
return (
|
||||
<>
|
||||
<Head><title>{websiteName}</title></Head>
|
||||
|
||||
<Container>
|
||||
<MessageList user={session.user} messages={messages}/>
|
||||
<FormMessage user={session.user} chatId={id} />
|
||||
|
||||
<Flex gap={5} mt={5}>
|
||||
<Input type={"text"} colorScheme={'purple'} onChange={(evt) => setText(evt.target.value) } value={text} />
|
||||
<Button colorScheme={'purple'} onClick={handleSubmit}>Envoyer</Button>
|
||||
</Flex>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -41,7 +41,7 @@ export default function Dashboard() {
|
||||
minH={"100vh"}
|
||||
>
|
||||
<GridItem area={"1 / 1 / 3 / 2"}>
|
||||
<LeftPanel user={refinedUser} />
|
||||
<LeftPanel user={user} />
|
||||
</GridItem>
|
||||
<GridItem area={"1 / 2 / 3 / 4"}>
|
||||
<Box py={3}>
|
||||
|
||||
@@ -25,7 +25,9 @@ import {
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
|
||||
import ModalModifyImages from "@/components/ModalModifyImages";
|
||||
import ModalModifyImages from "@/components/layout/user_profile/ModalModifyImages";
|
||||
import ModalChoosePassion from "@/components/layout/user_profile/ModalChoosePassion";
|
||||
import ProfileBadgeList from "@/components/layout/user_profile/ProfileBadgeList";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
@@ -33,6 +35,8 @@ import { useForm, Controller } from "react-hook-form";
|
||||
export default function UserProfile() {
|
||||
const router = useRouter();
|
||||
const toast = useToast();
|
||||
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const {
|
||||
@@ -82,6 +86,7 @@ export default function UserProfile() {
|
||||
.then((res) => {
|
||||
setIsLoading(false);
|
||||
toast({
|
||||
position:'top',
|
||||
title: `Modifications effectuées`,
|
||||
status: "success",
|
||||
isClosable: true,
|
||||
@@ -92,6 +97,7 @@ export default function UserProfile() {
|
||||
setIsLoading(false);
|
||||
toast({
|
||||
title: `Erreur lors de l'envoi des modifications`,
|
||||
position :'top',
|
||||
status: "error",
|
||||
isClosable: true,
|
||||
});
|
||||
@@ -299,6 +305,24 @@ export default function UserProfile() {
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Divider colorScheme={"purple"} />
|
||||
<Box my={"1rem"}>
|
||||
<Box>
|
||||
<FormLabel as={"legend"} htmlFor={"passion"}>
|
||||
Centre d'intéret :
|
||||
</FormLabel>
|
||||
<Controller
|
||||
name={"passion"}
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<>
|
||||
<ProfileBadgeList passions={user.passion !== undefined ? user.passion : []}/>
|
||||
<ModalChoosePassion user={user}/>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Divider colorScheme={"purple"} />
|
||||
<Box my={"1rem"}>
|
||||
<Box>
|
||||
<FormLabel as={"legend"} htmlFor={"gender"}>
|
||||
@@ -316,9 +340,6 @@ export default function UserProfile() {
|
||||
defaultValue={
|
||||
user.gender === null ? Gender.UNKNOWN : user.gender
|
||||
}
|
||||
// onChange={(value) => {
|
||||
// setUserData({ ...userData, gender: value });
|
||||
// }}
|
||||
>
|
||||
<HStack spacing={"0.5rem"}>
|
||||
<Radio value={Gender.MALE}>
|
||||
@@ -372,7 +393,7 @@ export default function UserProfile() {
|
||||
</Flex> */}
|
||||
</Box>
|
||||
<Divider colorScheme={"purple"} />
|
||||
<Center my={"1rem"}>
|
||||
<Center gap={"1rem"} my={"1rem"}>
|
||||
<Button
|
||||
colorScheme={"purple"}
|
||||
isLoading={isLoading}
|
||||
@@ -380,6 +401,13 @@ export default function UserProfile() {
|
||||
>
|
||||
Sauvegarder les modifications
|
||||
</Button>
|
||||
<Button
|
||||
colorScheme={"purple"}
|
||||
variant='outline'
|
||||
onClick={() => router.push("/dashboard")}
|
||||
>
|
||||
Retour
|
||||
</Button>
|
||||
</Center>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
Reference in New Issue
Block a user