diff --git a/jam-ui/package-lock.json b/jam-ui/package-lock.json index 091d969b0..1b0d87de1 100644 --- a/jam-ui/package-lock.json +++ b/jam-ui/package-lock.json @@ -3301,6 +3301,11 @@ "prop-types": "^15.6.1" } }, + "@filestack/loader": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@filestack/loader/-/loader-1.0.9.tgz", + "integrity": "sha512-zvXbZSgeybT1p3ds5NZ5GQYPVnKacgb2YGWe7psdPs/JE1v3SL1j2SXYaHA/f/Qwc8Y1fjzz53maKP0vwDHrvA==" + }, "@fortawesome/fontawesome-common-types": { "version": "0.2.35", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz", @@ -3853,6 +3858,61 @@ } } }, + "@sentry/hub": { + "version": "6.19.7", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.19.7.tgz", + "integrity": "sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==", + "requires": { + "@sentry/types": "6.19.7", + "@sentry/utils": "6.19.7", + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@sentry/minimal": { + "version": "6.19.7", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.19.7.tgz", + "integrity": "sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ==", + "requires": { + "@sentry/hub": "6.19.7", + "@sentry/types": "6.19.7", + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@sentry/types": { + "version": "6.19.7", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.19.7.tgz", + "integrity": "sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==" + }, + "@sentry/utils": { + "version": "6.19.7", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.19.7.tgz", + "integrity": "sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==", + "requires": { + "@sentry/types": "6.19.7", + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "@socket.io/component-emitter": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", @@ -3968,6 +4028,11 @@ "loader-utils": "^1.2.3" } }, + "@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + }, "@types/babel__core": { "version": "7.1.14", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", @@ -4688,6 +4753,11 @@ } } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -7887,6 +7957,11 @@ "integrity": "sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, "diff-sequences": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", @@ -9632,6 +9707,14 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fast-xml-parser": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.3.tgz", + "integrity": "sha512-coV/D1MhrShMvU6D0I+VAK3umz6hUaxxhL0yp/9RjfiYUfAv14rDhGQL+PLForhMdr0wq3PiV07WtkkNjJjNHg==", + "requires": { + "strnum": "^1.0.5" + } + }, "fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -9721,6 +9804,16 @@ "tslib": "^2.0.1" } }, + "file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "requires": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + } + }, "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -9732,6 +9825,48 @@ "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.0.1.tgz", "integrity": "sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg==" }, + "filestack-js": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/filestack-js/-/filestack-js-3.30.0.tgz", + "integrity": "sha512-t8eBumzitZhdWEw+WqUY5QFf5uAEEObj3qsZRvb6g5AdluNtiWhF5ujqrES1l4xwzDp1v+dzItaAwzAwYcyu5w==", + "requires": { + "@babel/runtime": "^7.8.4", + "@filestack/loader": "^1.0.9", + "@sentry/minimal": "^6.19.7", + "abab": "^2.0.6", + "debug": "^4.3.4", + "eventemitter3": "^5.0.0", + "fast-xml-parser": "^4.2.4", + "file-type": "^16.5.4", + "follow-redirects": "^1.15.2", + "isutf8": "^4.0.0", + "jsonschema": "^1.4.1", + "lodash.clonedeep": "^4.5.0", + "p-queue": "^6.6.2", + "spark-md5": "^3.0.2", + "ts-node": "^8.10.2" + }, + "dependencies": { + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + } + } + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -12178,6 +12313,11 @@ "html-escaper": "^2.0.0" } }, + "isutf8": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isutf8/-/isutf8-4.0.0.tgz", + "integrity": "sha512-mJtsQGFfAphKdVuRitEpc0eon4v5fuaB6v9ZJIrLnIyybh02sIIwJ2RQbLMp6UICVCfquezllupZIVcqzGzCPg==" + }, "jest": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", @@ -12838,6 +12978,11 @@ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" }, + "jsonschema": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==" + }, "jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -13396,6 +13541,11 @@ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -13531,6 +13681,11 @@ } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -14989,6 +15144,22 @@ "aggregate-error": "^3.0.0" } }, + "p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "requires": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "dependencies": { + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + } + } + }, "p-reduce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", @@ -15002,6 +15173,14 @@ "retry": "^0.12.0" } }, + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "requires": { + "p-finally": "^1.0.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -15226,6 +15405,11 @@ "sha.js": "^2.4.8" } }, + "peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==" + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -17595,6 +17779,14 @@ "util-deprecate": "^1.0.1" } }, + "readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "requires": { + "readable-stream": "^3.6.0" + } + }, "readdirp": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", @@ -18984,6 +19176,11 @@ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" }, + "spark-md5": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", + "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==" + }, "sparkles": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", @@ -19491,6 +19688,20 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, + "strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "requires": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + } + }, "style-loader": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", @@ -19988,6 +20199,15 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, + "token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "requires": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + } + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -20020,6 +20240,18 @@ "glob": "^7.1.2" } }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, "ts-pnp": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.6.tgz", @@ -21781,6 +22013,11 @@ "decamelize": "^1.2.0" } }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + }, "zoom-level": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/zoom-level/-/zoom-level-2.5.0.tgz", diff --git a/jam-ui/package.json b/jam-ui/package.json index f8d8d3af0..e002581c0 100644 --- a/jam-ui/package.json +++ b/jam-ui/package.json @@ -30,6 +30,7 @@ "element-resize-event": "^3.0.3", "emoji-mart": "^3.0.0", "faker": "^5.5.3", + "filestack-js": "^3.30.0", "fuse.js": "^6.4.3", "google-maps-react": "^2.0.6", "i18next": "^21.3.3", diff --git a/jam-ui/src/components/page/JKEditProfile.js b/jam-ui/src/components/page/JKEditProfile.js index a1b606507..adcf00f67 100644 --- a/jam-ui/src/components/page/JKEditProfile.js +++ b/jam-ui/src/components/page/JKEditProfile.js @@ -4,6 +4,8 @@ import Select from 'react-select'; import FalconCardHeader from '../common/FalconCardHeader'; import { useTranslation } from 'react-i18next'; import JKCurrentUserAvatar from '../navbar/JKCurrentUserAvatar'; +import JKModalDialog from '../common/JKModalDialog'; +import JKAvatarUpload from '../profile/JKAvatarUpload'; import { useAuth } from '../../context/UserAuth'; import { useForm, Controller } from 'react-hook-form'; import { @@ -27,6 +29,7 @@ function JKEditProfile() { const [countries, setCountries] = useState([]); const [regions, setRegions] = useState([]); const [cities, setCities] = useState([]); + const [showAvatarModal, setShowAvatarModal] = useState(false); const [_, forceUpdate] = useReducer(x => x + 1, 0); @@ -308,6 +311,10 @@ function JKEditProfile() { handleChange(); }; + const toggleShowAvatarModel = () => { + setShowAvatarModal(!showAvatarModal); + }; + const handleChange = () => { const params = getValues(); const data = { @@ -336,318 +343,320 @@ function JKEditProfile() { }; return ( - - - -
- - - - -
Basics
-
- - - - - - ( - { - onChange(e); - handleTextInputChage(); - }} - /> - )} - /> - - - - - - ( - { - onChange(e); - handleTextInputChage(); - }} - /> - )} - /> - - - -
-
- -
- -
- -
- - - - - {countries.length > 0 && ( + <> + + + + + + + + +
Basics
+
+ + + + + { - const country = countries.find(country => country.countrycode === value); - return ( - { - return { value: region.region, label: region.region }; - })} - /> - ); - }} - /> - )} - - - - - - ( - { - onChange(e); - handleTextInputChage(); - }} - /> - )} - /> - - - ( - { - onChange(e); - handleChange(); - }} - /> - )} - /> - - - -
- - - -
Interests
-
- - - ( - { - onChange(e); - handleChange(); - }} - type="checkbox" - /> - )} - /> - - - - ( - { - onChange(e); - handleChange(); - }} - type="checkbox" - /> - )} - /> - - - - ( - { - onChange(e); - handleChange(); - }} - type="checkbox" - /> - )} - /> - - - -
- - - - -
Instruments
-
- - - {instrumentsInitialLoadingDone && - musicInstruments.map((musicInstrument, index) => { - return ( - - + render={({ field: { onChange, value } }) => ( { - handleInstrumentSelect(e, musicInstrument); + onChange(e); + handleTextInputChage(); }} - type="checkbox" - checked={musicInstrument.checked} /> - - - - + )} + /> + + + + + + ( + { + onChange(e); + handleTextInputChage(); + }} + /> + )} + /> + + + + + +
+ + + + + {countries.length > 0 && ( + { + const country = countries.find(country => country.countrycode === value); + return ( + { + return { value: region.region, label: region.region }; + })} + /> + ); + }} + /> + )} + + + + + + ( { - handleGenreChange(e, genre); - }} - type="checkbox" - checked={genre.checked} - /> - - - - ); - })} -
-
-
- -
-
-
-
+ )} + /> + + + + + + ( + { + onChange(e); + handleTextInputChage(); + }} + /> + )} + /> + + + ( + { + onChange(e); + handleChange(); + }} + /> + )} + /> + + + + + + + +
Interests
+
+ + + ( + { + onChange(e); + handleChange(); + }} + type="checkbox" + /> + )} + /> + + + + ( + { + onChange(e); + handleChange(); + }} + type="checkbox" + /> + )} + /> + + + + ( + { + onChange(e); + handleChange(); + }} + type="checkbox" + /> + )} + /> + + + +
+ + + + +
Instruments
+
+ + + {instrumentsInitialLoadingDone && + musicInstruments.map((musicInstrument, index) => { + return ( + + + { + handleInstrumentSelect(e, musicInstrument); + }} + type="checkbox" + checked={musicInstrument.checked} + /> + + + + + { + handleGenreChange(e, genre); + }} + type="checkbox" + checked={genre.checked} + /> + + + + ); + })} + + +
+ + + + + + + ); } diff --git a/jam-ui/src/components/profile/JKAvatarUpload.js b/jam-ui/src/components/profile/JKAvatarUpload.js new file mode 100644 index 000000000..3d7045bd0 --- /dev/null +++ b/jam-ui/src/components/profile/JKAvatarUpload.js @@ -0,0 +1,140 @@ +import React, { useEffect, useRef, useState } from 'react'; +import JKModalDialog from '../common/JKModalDialog'; +import { Button, Card, CardBody } from 'reactstrap'; +import { useTranslation } from 'react-i18next'; +import * as filestack from 'filestack-js'; +import { getFilepickerPolicy } from '../../helpers/rest'; +import { useAuth } from '../../context/UserAuth'; +import { getUserDetails, updateAvatar } from '../../helpers/rest'; + +const JKAvatarUpload = ({ show, onToggle }) => { + const { t } = useTranslation(); + const client = useRef(null); + const { currentUser } = useAuth(); + const [userDetails, setUserDetails] = useState(null); + + useEffect(() => { + if (currentUser) { + //get user details + getUserDetails(currentUser.id) + .then(response => { + if (response.status === 200) { + return response.json(); + } else { + console.log('getUserDetails error', response); + } + }) + .then(user => { + console.log('userDetails', user); + setUserDetails(user); + }) + .catch(error => { + console.log('getUserDetails error', error); + }); + } + }, [currentUser]); + + useEffect(() => { + if (currentUser && window.gon && window.gon.fp_apikey) { + getFilepickerPolicy(currentUser.id) + .then(response => { + if (response.status === 200) { + return response.json(); + } else { + console.log('getFilepickerPolicy error', response); + } + }) + .then(filepicker_policy => { + console.log('filepicker_policy', filepicker_policy); + console.log('currentUser', currentUser); + + const options = { + security: { + policy: filepicker_policy.policy, + signature: filepicker_policy.signature + } + }; + client.current = filestack.init(window.gon.fp_apikey, options); + + //render avatar + }) + .catch(error => { + console.log('getFilepickerPolicy error', error); + }); + } + }, [currentUser, window.gon]); + + useEffect(() => { + if (userDetails) { + //render avatar + } + }, [userDetails]); + + const openFilePicker = () => { + client.current + .picker({ + accept: ['image/*'], + maxFiles: 1, + transformations: { + crop: { + aspectRatio: 1, + force: true + }, + circle: true, + rotate: true + }, + onFileSelected: file => { + console.log('file selected', file); + }, + onUploadDone: res => { + console.log('upload done', res); + + // updateAvatar({ + // original_fpfile: determineCurrentFpfile(), + // cropped_fpfile: scaled, + // cropped_large_fpfile: scaledLarger, + // crop_selection: currentSelection + // }) + // .then(response => { + // if (response.status === 200) { + // return response.json(); + // } else { + // console.log('updateAvatar error', response); + // } + // }) + // .then(user => { + // console.log('updateAvatar', user); + // setUserDetails(user); + // }) + // .catch(error => { + // console.log('updateAvatar error', error); + // }); + } + }) + .open(); + }; + + return ( + + {userDetails && userDetails.original_fpfile ? ( +
{userDetails.original_fpfile}
+ ) : ( + + +
{t('avatar_modal.no_avatar', { ns: 'profile' })}
+
+
+ )} +
+ + +
+
+ ); +}; + +export default JKAvatarUpload; diff --git a/jam-ui/src/helpers/rest.js b/jam-ui/src/helpers/rest.js index f6ec11d3d..338089524 100644 --- a/jam-ui/src/helpers/rest.js +++ b/jam-ui/src/helpers/rest.js @@ -1,12 +1,12 @@ -import apiFetch from "./apiFetch"; +import apiFetch from './apiFetch'; -export const getMusicians = (page) => { +export const getMusicians = page => { return new Promise((resolve, reject) => { apiFetch(`/search/musicians?results=true`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; // export const getPeople = (page) => { // return new Promise((resolve, reject) => { @@ -16,48 +16,48 @@ export const getMusicians = (page) => { // }) // } -export const getPersonById = (id) => { - return new Promise((resolve, reject) => ( +export const getPersonById = id => { + return new Promise((resolve, reject) => apiFetch(`/users/${id}/profile?show_teacher=true`) - .then(response => resolve(response)) - .catch(error => reject(error)) - )) -} + .then(response => resolve(response)) + .catch(error => reject(error)) + ); +}; export const getPeople = ({ data, offset, limit } = {}) => { return new Promise((resolve, reject) => { apiFetch(`/filter?offset=${offset}&limit=${limit}`, { method: 'POST', - body: JSON.stringify(data) + body: JSON.stringify(data) }) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const getPeopleIndex = () => { return new Promise((resolve, reject) => { apiFetch(`/users`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const getGenres = () => { return new Promise((resolve, reject) => { apiFetch('/genres') - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const getInstruments = () => { return new Promise((resolve, reject) => { apiFetch('/instruments') - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; // export const getCurrentUser = () => { // return new Promise((resolve, reject) => { @@ -67,13 +67,13 @@ export const getInstruments = () => { // }) // } -export const getFriends = (userId) => { +export const getFriends = userId => { return new Promise((resolve, reject) => { apiFetch(`/users/${userId}/friends`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const addFriend = (userId, friendId) => { return new Promise((resolve, reject) => { @@ -81,108 +81,106 @@ export const addFriend = (userId, friendId) => { method: 'POST', body: JSON.stringify({ friend_id: friendId }) }) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const removeFriend = (userId, friendId) => { return new Promise((resolve, reject) => { apiFetch(`/users/${userId}/friends/${friendId}`, { method: 'DELETE' }) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const getTextMessages = (options = {}) => { return new Promise((resolve, reject) => { apiFetch(`/text_messages?${new URLSearchParams(options)}`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; -export const createTextMessage = (options) => { +export const createTextMessage = options => { return new Promise((resolve, reject) => { apiFetch(`/text_messages`, { - method: "POST", + method: 'POST', body: JSON.stringify(options) }) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; -export const createLobbyChatMessage = (options) => { +export const createLobbyChatMessage = options => { return new Promise((resolve, reject) => { apiFetch(`/chat`, { - method: "POST", + method: 'POST', body: JSON.stringify(options) }) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const getNotifications = (userId, options = {}) => { return new Promise((resolve, reject) => { apiFetch(`/users/${userId}/notifications?${new URLSearchParams(options)}`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) - -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const acceptFriendRequest = (userId, options = {}) => { return new Promise((resolve, reject) => { - const { status, friend_request_id } = options + const { status, friend_request_id } = options; apiFetch(`/users/${userId}/friend_requests/${friend_request_id}`, { method: 'POST', body: JSON.stringify({ status }) }) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const deleteNotification = (userId, notificationId) => { return new Promise((resolve, reject) => { apiFetch(`/users/${userId}/notifications/${notificationId}`, { - method: 'DELETE', + method: 'DELETE' }) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const getSessions = () => { return new Promise((resolve, reject) => { apiFetch(`/sessions`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const getLatencyToUsers = (currentUserId, participantIds) => { return new Promise((resolve, reject) => { - const query = participantIds.map(id => `user_ids[]=${id}`).join('&') + const query = participantIds.map(id => `user_ids[]=${id}`).join('&'); apiFetch(`/users/${currentUserId}/latencies?${query}`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const getLobbyChatMessages = (options = {}) => { return new Promise((resolve, reject) => { - console.log('getLobbyChatMessages', options) + console.log('getLobbyChatMessages', options); apiFetch(`/chat?${new URLSearchParams(options)}`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} - + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const updateUser = (userId, options) => { return new Promise((resolve, reject) => { @@ -190,32 +188,66 @@ export const updateUser = (userId, options) => { method: 'PATCH', body: JSON.stringify(options) }) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; +export const getUserDetails = userId => { + return new Promise((resolve, reject) => { + apiFetch(`/users/${userId}`) + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const getCountries = () => { return new Promise((resolve, reject) => { apiFetch(`/countries`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; -export const getRegions = (countryId) => { +export const getRegions = countryId => { return new Promise((resolve, reject) => { apiFetch(`/regions?country=${countryId}`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; export const getCities = (countryId, regionId) => { return new Promise((resolve, reject) => { apiFetch(`/cities?country=${countryId}®ion=${regionId}`) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) -} \ No newline at end of file + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; + +export const getFilepickerPolicy = (userId, options) => { + let params = {}; + if (options && options['handle']) { + params['handle'] = options['handle']; + } + if (options && options['convert']) { + params['convert'] = options['convert']; + } + const url = '/users/' + userId + '/filepicker_policy?' + new URLSearchParams(params); + return new Promise((resolve, reject) => { + apiFetch(url) + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +}; + +export const updateAvatar = (userId, options) => { + return new Promise((resolve, reject) => { + apiFetch(`/users/${userId}/avatar`, { + method: 'PATCH', + body: JSON.stringify(options) + }) + .then(response => resolve(response)) + .catch(error => reject(error)); + }); +} diff --git a/jam-ui/src/i18n/locales/en/profile.json b/jam-ui/src/i18n/locales/en/profile.json index 2eade7bb7..d438068b5 100644 --- a/jam-ui/src/i18n/locales/en/profile.json +++ b/jam-ui/src/i18n/locales/en/profile.json @@ -1,3 +1,17 @@ { - "page_title": "Profile" + "page_title": "Profile", + "change_photo": "Change Photo", + "avatar_modal": { + "title": "Update Profile Photo", + "upload": "Upload", + "cancel": "Cancel", + "delete": "Delete", + "save": "Save", + "upload_photo": "Please upload a photo", + "no_avatar": "Please upload a photo.", + "error": { + "file_type": "Invalid file type. Please upload a JPG or PNG image.", + "upload": "There was an error uploading your avatar. Please try again." + } + } }