diff --git a/frontend/package.json b/frontend/package.json index 8ec31f4..57d0bd5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,8 +8,10 @@ "lint": "next lint" }, "dependencies": { + "@codemirror/lang-markdown": "^6.0.5", "@sentry/nextjs": "^7.20.0", "@types/lodash": "^4.14.189", + "@uiw/react-codemirror": "^4.15.1", "lodash": "^4.17.21", "next": "13.0.4", "react": "18.2.0", @@ -21,6 +23,12 @@ "sortablejs": "^1.15.0", "toastify-js": "^1.12.0" }, + "overrides": { + "@codemirror/highlight": "0.19.8", + "@codemirror/lang-markdown": "^6.0.5", + "@codemirror/state": ">=6.0.0", + "@codemirror/view": ">=6.0.0" + }, "devDependencies": { "@tailwindcss/forms": "^0.5.2", "@tailwindcss/typography": "^0.5.3", diff --git a/frontend/pages/edit/profile.tsx b/frontend/pages/edit/profile.tsx index 89d5ed5..93bff8d 100644 --- a/frontend/pages/edit/profile.tsx +++ b/frontend/pages/edit/profile.tsx @@ -1,5 +1,5 @@ import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { useRecoilState } from "recoil"; import Loading from "../../components/Loading"; import fetchAPI from "../../lib/fetch"; @@ -18,11 +18,22 @@ import Button, { ButtonStyle } from "../../components/Button"; import { Plus, Save, Trash } from "react-bootstrap-icons"; import toast from "../../lib/toast"; +import ReactCodeMirror from "@uiw/react-codemirror"; +import { markdown, markdownLanguage } from "@codemirror/lang-markdown"; +import ReactMarkdown from "react-markdown"; + export default function Index() { const [user, setUser] = useRecoilState(userState); const router = useRouter(); const [state, setState] = useState(cloneDeep(user)); + const onChangeBio = useCallback((value: string, viewUpdate: any) => { + setState((s) => { + s!.bio = value; + return s; + }); + }, []); + const originalOrder = state?.fields ? state.fields.map((f, i) => { const field: EditField = { @@ -52,9 +63,11 @@ export default function Index() { : []; const [fields, setFields] = useState(cloneDeep(originalOrder)); + const resetFields = () => { setFields(cloneDeep(originalOrder)); }; + const addField = () => { if (fields.length >= 25) return; @@ -98,6 +111,24 @@ export default function Index() { )} +

+ Bio +

+
+
+

Edit

+ +
+
+

Preview

+ {state?.bio || ""} +
+
+

Fields
@@ -249,6 +280,6 @@ async function updateUser(args: { return user; } catch (e: any) { - toast({ text: `${e.message ?? e}`, background: "error" }); + toast({ text: `${e.details ?? e.message ?? e}`, background: "error" }); } } diff --git a/frontend/yarn.lock b/frontend/yarn.lock index fe45035..d85da44 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -17,6 +17,136 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.18.6": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9" + integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg== + dependencies: + regenerator-runtime "^0.13.10" + +"@codemirror/autocomplete@^6.0.0": + version "6.3.3" + resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.3.3.tgz#f9dba421b9a0d83ecf89a06def37a96e6afb593a" + integrity sha512-8MGqPuKvE0W0XjabDYX3BFJNJRsYFAYpDBol+YCg6o5t2JyoDeoMYrqRMVnJv1B1FBgNAkvdDVrNrVE/7c9qvQ== + dependencies: + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.5.0" + "@lezer/common" "^1.0.0" + +"@codemirror/commands@^6.0.0", "@codemirror/commands@^6.1.0": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.1.2.tgz#84fb7d170047c3aeb7b0047ace59510bb19208de" + integrity sha512-sO3jdX1s0pam6lIdeSJLMN3DQ6mPEbM4yLvyKkdqtmd/UDwhXA5+AwFJ89rRXm6vTeOXBsE5cAmlos/t7MJdgg== + dependencies: + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + "@lezer/common" "^1.0.0" + +"@codemirror/lang-css@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@codemirror/lang-css/-/lang-css-6.0.1.tgz#470fff614e4cfbbe796ec43103420d59c797dd7a" + integrity sha512-rlLq1Dt0WJl+2epLQeAsfqIsx3lGu4HStHCJu95nGGuz2P2fNugbU3dQYafr2VRjM4eMC9HviI6jvS98CNtG5w== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@lezer/css" "^1.0.0" + +"@codemirror/lang-html@^6.0.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@codemirror/lang-html/-/lang-html-6.2.0.tgz#f6208194c351b5b1d955206b703159bad13d8e29" + integrity sha512-0Kr+gWPu1J4mhpLbqHPqoD5+xLCwAntfzRv9L61cqRSFNpDpDbGbONSN5xzWupo6AJ9qtDOlJNBFBuL72tXPwg== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/lang-css" "^6.0.0" + "@codemirror/lang-javascript" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.2.2" + "@lezer/common" "^1.0.0" + "@lezer/html" "^1.1.0" + +"@codemirror/lang-javascript@^6.0.0": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@codemirror/lang-javascript/-/lang-javascript-6.1.1.tgz#f920192db30531927a02b8a1af9cf3c3d895101c" + integrity sha512-F4+kiuC5d5dUSJmff96tJQwpEXs/tX/4bapMRnZWW6bHKK1Fx6MunTzopkCUWRa9bF87GPmb9m7Qtg7Yv8f3uQ== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/lint" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + "@lezer/common" "^1.0.0" + "@lezer/javascript" "^1.0.0" + +"@codemirror/lang-markdown@^6.0.5": + version "6.0.5" + resolved "https://registry.yarnpkg.com/@codemirror/lang-markdown/-/lang-markdown-6.0.5.tgz#61393c7e2552528daee6aa4eca63428aa00832bd" + integrity sha512-qH0THRYc2M7pIJoAp6jstXZkv8ZMVhNaBm7Bs4+0SLHhHlwX53txFy98AcPwrfq0Sh8Zi6RAuj9j/GyL8E1MKw== + dependencies: + "@codemirror/lang-html" "^6.0.0" + "@codemirror/language" "^6.3.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + "@lezer/common" "^1.0.0" + "@lezer/markdown" "^1.0.0" + +"@codemirror/language@^6.0.0", "@codemirror/language@^6.3.0": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.3.1.tgz#1d61f33aa5de9aa74a713ee1f5ce600adc74df6b" + integrity sha512-MK+G1QKaGfSEUg9YEFaBkMBI6j1ge4VMBPZv9fDYotw7w695c42x5Ba1mmwBkesYnzYFBfte6Hh9TDcKa6xORQ== + dependencies: + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + "@lezer/common" "^1.0.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + style-mod "^4.0.0" + +"@codemirror/lint@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.1.0.tgz#f006142d3a580fdb8ffc2faa3361b2232c08e079" + integrity sha512-mdvDQrjRmYPvQ3WrzF6Ewaao+NWERYtpthJvoQ3tK3t/44Ynhk8ZGjTSL9jMEv8CgSMogmt75X8ceOZRDSXHtQ== + dependencies: + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + crelt "^1.0.5" + +"@codemirror/search@^6.0.0": + version "6.2.3" + resolved "https://registry.yarnpkg.com/@codemirror/search/-/search-6.2.3.tgz#fab933fef1b1de8ef40cda275c73d9ac7a1ff40f" + integrity sha512-V9n9233lopQhB1dyjsBK2Wc1i+8hcCqxl1wQ46c5HWWLePoe4FluV3TGHoZ04rBRlGjNyz9DTmpJErig8UE4jw== + dependencies: + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + crelt "^1.0.5" + +"@codemirror/state@^6.0.0", "@codemirror/state@^6.1.1", "@codemirror/state@^6.1.4": + version "6.1.4" + resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.1.4.tgz#2b654ae233ac4f41ee89ce095509ea35ecdf1031" + integrity sha512-g+3OJuRylV5qsXuuhrc6Cvs1NQluNioepYMM2fhnpYkNk7NgX+j0AFuevKSVKzTDmDyt9+Puju+zPdHNECzCNQ== + +"@codemirror/theme-one-dark@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@codemirror/theme-one-dark/-/theme-one-dark-6.1.0.tgz#6f8b3c7fc22e9fec59edd573f4ba9546db42e007" + integrity sha512-AiTHtFRu8+vWT9wWUWDM+cog6ZwgivJogB1Tm/g40NIpLwph7AnmxrSzWfvJN5fBVufsuwBxecQCNmdcR5D7Aw== + dependencies: + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + "@lezer/highlight" "^1.0.0" + +"@codemirror/view@^6.0.0", "@codemirror/view@^6.2.2", "@codemirror/view@^6.5.0": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.5.1.tgz#f4533cd796f0569508822d0012bee9a15dc4b3f9" + integrity sha512-xBKP8N3AXOs06VcKvIuvIQoUlGs7Hb78ftJWahLaRX909jKPMgGxR5XjvrawzTTZMSTU3DzdjDNPwG6fPM/ypQ== + dependencies: + "@codemirror/state" "^6.1.4" + style-mod "^4.0.0" + w3c-keyname "^2.2.4" + "@eslint/eslintrc@^1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" @@ -46,6 +176,58 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@lezer/common@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@lezer/common/-/common-1.0.2.tgz#8fb9b86bdaa2ece57e7d59e5ffbcb37d71815087" + integrity sha512-SVgiGtMnMnW3ActR8SXgsDhw7a0w0ChHSYAyAUxxrOiJ1OqYWEKk/xJd84tTSPo1mo6DXLObAJALNnd0Hrv7Ng== + +"@lezer/css@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@lezer/css/-/css-1.0.1.tgz#589d16d557024481f38dd8a036be3c3db1a199c2" + integrity sha512-kLGsbzXdp1ntzO2jDwFf+2w76EBlLiD4FKofx7tgkdqeFRoslFiMS2qqbNtAauXw8ihZ4cE5YpxSpfsKXSs5Sg== + dependencies: + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/highlight@^1.0.0": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@lezer/highlight/-/highlight-1.1.2.tgz#60cd6c2a0a2cf753b8a026b04feeb0ea8df326ea" + integrity sha512-CAun1WR1glxG9ZdOokTZwXbcwB7PXkIEyZRUMFBVwSrhTcogWq634/ByNImrkUnQhjju6xsIaOBIxvcRJtplXQ== + dependencies: + "@lezer/common" "^1.0.0" + +"@lezer/html@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@lezer/html/-/html-1.1.1.tgz#eaf4fb45f5f6deb0b6336e46a5e9620300e920ff" + integrity sha512-L70zLh1+bemYcnaAK03Ghfu24DVxY9uScDawyjR1Y/13P2MbN72hMB9T7Ln/Vl5dL5DWI0YsxbaeIHKikx2DiQ== + dependencies: + "@lezer/common" "^1.0.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/javascript@^1.0.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@lezer/javascript/-/javascript-1.2.0.tgz#5ffc2f20494a2cd79e78c216512d018ace51c036" + integrity sha512-oUkbTNEFvERS5mFFBK8eJ3DufiNQvt1qghWbxwLAGb9h1qUexUHd9zuF0jbZj7AfnZwqkxfDc0q+Km3kaWzrLw== + dependencies: + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/lr@^1.0.0": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-1.2.5.tgz#e9088164a711690596f17378665e0554157c9b03" + integrity sha512-f9319YG1A/3ysgUE3bqCHEd7g+3ZZ71MWlwEc42mpnLVYXgfJJgtu1XAyBB4Kz8FmqmnFe9caopDqKeMMMAU6g== + dependencies: + "@lezer/common" "^1.0.0" + +"@lezer/markdown@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@lezer/markdown/-/markdown-1.0.2.tgz#8c804a9f6fe1ccca4a20acd2fd9fbe0fae1ae178" + integrity sha512-8CY0OoZ6V5EzPjSPeJ4KLVbtXdLBd8V6sRCooN5kHnO28ytreEGTyrtU/zUwo/XLRzGr/e1g44KlzKi3yWGB5A== + dependencies: + "@lezer/common" "^1.0.0" + "@lezer/highlight" "^1.0.0" + "@next/env@13.0.4": version "13.0.4" resolved "https://registry.yarnpkg.com/@next/env/-/env-13.0.4.tgz#249a21be88fa61e1a712939db00b9d02764831f4" @@ -452,6 +634,31 @@ "@typescript-eslint/types" "5.43.0" eslint-visitor-keys "^3.3.0" +"@uiw/codemirror-extensions-basic-setup@4.15.1": + version "4.15.1" + resolved "https://registry.yarnpkg.com/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.15.1.tgz#acbd20e0299f7eb3b46ce490f23caf510f532951" + integrity sha512-LP2LHyPQm6ikYyXxT+1Odz+kiVLzzUmHSwBapSF4JgUE4b5QaBA7KCiTfwIWJPC528QVP2qWk1DEBNstPMiUdg== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/commands" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/lint" "^6.0.0" + "@codemirror/search" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + +"@uiw/react-codemirror@^4.15.1": + version "4.15.1" + resolved "https://registry.yarnpkg.com/@uiw/react-codemirror/-/react-codemirror-4.15.1.tgz#bc18e7d6016407249f4e055d070c7f3433471b61" + integrity sha512-lgtMFS8D2t9ri3ug3kgWoLPPdxDkqkYBWm3dVU9Z7GRs4R1iN2WSr2Z/biQ8KbdyLygRT5isi1k3Ud9ZY6j+YA== + dependencies: + "@babel/runtime" "^7.18.6" + "@codemirror/commands" "^6.1.0" + "@codemirror/state" "^6.1.1" + "@codemirror/theme-one-dark" "^6.0.0" + "@uiw/codemirror-extensions-basic-setup" "4.15.1" + codemirror "^6.0.0" + acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -763,6 +970,19 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== +codemirror@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-6.0.1.tgz#62b91142d45904547ee3e0e0e4c1a79158035a29" + integrity sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/commands" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/lint" "^6.0.0" + "@codemirror/search" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -810,6 +1030,11 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +crelt@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/crelt/-/crelt-1.0.5.tgz#57c0d52af8c859e354bace1883eb2e1eb182bb94" + integrity sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA== + cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -2696,6 +2921,11 @@ recoil@^0.7.5: dependencies: hamt_plus "1.0.2" +regenerator-runtime@^0.13.10: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-runtime@^0.13.4: version "0.13.9" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" @@ -2960,6 +3190,11 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +style-mod@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.0.0.tgz#97e7c2d68b592975f2ca7a63d0dd6fcacfe35a01" + integrity sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw== + style-to-object@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" @@ -3276,6 +3511,11 @@ vfile@^5.0.0: unist-util-stringify-position "^3.0.0" vfile-message "^3.0.0" +w3c-keyname@^2.2.4: + version "2.2.6" + resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.6.tgz#8412046116bc16c5d73d4e612053ea10a189c85f" + integrity sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"