From 3cd8eadee36e9fdbb2794d015ea218aa7e4afb8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20van=20Br=C3=BCgge?= Date: Tue, 8 Oct 2024 16:24:09 +0100 Subject: [PATCH 01/33] Update prisma to v5 --- package.json | 4 ++-- yarn.lock | 67 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 08502171..ab3d816e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@aws-sdk/client-s3": "^3.379.1", "@headlessui/react": "^1.7.15", "@mozilla/readability": "^0.4.4", - "@prisma/client": "^4.16.2", + "@prisma/client": "^5.20.0", "@stripe/stripe-js": "^1.54.1", "@tanstack/react-query": "^5.51.15", "@tanstack/react-query-devtools": "^5.51.15", @@ -91,7 +91,7 @@ "nodemon": "^3.0.2", "postcss": "^8.4.26", "prettier": "3.1.1", - "prisma": "^4.16.2", + "prisma": "^5.20.0", "tailwindcss": "^3.3.3", "ts-node": "^10.9.2", "typescript": "4.9.4" diff --git a/yarn.lock b/yarn.lock index edf50401..c5362b54 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1300,22 +1300,46 @@ dependencies: playwright "1.45.0" -"@prisma/client@^4.16.2": - version "4.16.2" - resolved "https://registry.yarnpkg.com/@prisma/client/-/client-4.16.2.tgz#3bb9ebd49b35c8236b3d468d0215192267016e2b" - integrity sha512-qCoEyxv1ZrQ4bKy39GnylE8Zq31IRmm8bNhNbZx7bF2cU5aiCCnSa93J2imF88MBjn7J9eUQneNxUQVJdl/rPQ== +"@prisma/client@^5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.20.0.tgz#4fc9f2b2341c9c997c139df4445688dd6b39663b" + integrity sha512-CLv55ZuMuUawMsxoqxGtLT3bEZoa2W8L3Qnp6rDIFWy+ZBrUcOFKdoeGPSnbBqxc3SkdxJrF+D1veN/WNynZYA== + +"@prisma/debug@5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.20.0.tgz#c6d1cf6e3c6e9dba150347f13ca200b1d66cc9fc" + integrity sha512-oCx79MJ4HSujokA8S1g0xgZUGybD4SyIOydoHMngFYiwEwYDQ5tBQkK5XoEHuwOYDKUOKRn/J0MEymckc4IgsQ== + +"@prisma/engines-version@5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284": + version "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284.tgz#9a53b13cdcfd706ae54198111000f33c63655c39" + integrity sha512-Lg8AS5lpi0auZe2Mn4gjuCg081UZf88k3cn0RCwHgR+6cyHHpttPZBElJTHf83ZGsRNAmVCZCfUGA57WB4u4JA== + +"@prisma/engines@5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.20.0.tgz#86fe407e55219d33d03ebc26dc829a422faed545" + integrity sha512-DtqkP+hcZvPEbj8t8dK5df2b7d3B8GNauKqaddRRqQBBlgkbdhJkxhoJTrOowlS3vaRt2iMCkU0+CSNn0KhqAQ== dependencies: - "@prisma/engines-version" "4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81" + "@prisma/debug" "5.20.0" + "@prisma/engines-version" "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284" + "@prisma/fetch-engine" "5.20.0" + "@prisma/get-platform" "5.20.0" -"@prisma/engines-version@4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81": - version "4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81" - resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81.tgz#d3b5dcf95b6d220e258cbf6ae19b06d30a7e9f14" - integrity sha512-q617EUWfRIDTriWADZ4YiWRZXCa/WuhNgLTVd+HqWLffjMSPzyM5uOWoauX91wvQClSKZU4pzI4JJLQ9Kl62Qg== +"@prisma/fetch-engine@5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.20.0.tgz#b917880fb08f654981f14ca49923031b39683586" + integrity sha512-JVcaPXC940wOGpCOwuqQRTz6I9SaBK0c1BAyC1pcz9xBi+dzFgUu3G/p9GV1FhFs9OKpfSpIhQfUJE9y00zhqw== + dependencies: + "@prisma/debug" "5.20.0" + "@prisma/engines-version" "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284" + "@prisma/get-platform" "5.20.0" -"@prisma/engines@4.16.2": - version "4.16.2" - resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-4.16.2.tgz#5ec8dd672c2173d597e469194916ad4826ce2e5f" - integrity sha512-vx1nxVvN4QeT/cepQce68deh/Turxy5Mr+4L4zClFuK1GlxN3+ivxfuv+ej/gvidWn1cE1uAhW7ALLNlYbRUAw== +"@prisma/get-platform@5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.20.0.tgz#c1a53a8d8af67f2b4a6b97dd4d25b1c603236804" + integrity sha512-8/+CehTZZNzJlvuryRgc77hZCWrUDYd/PmlZ7p2yNXtmf2Una4BWnTbak3us6WVdqoz5wmptk6IhsXdG2v5fmA== + dependencies: + "@prisma/debug" "5.20.0" "@radix-ui/primitive@1.0.1": version "1.0.1" @@ -3533,6 +3557,11 @@ fsevents@2.3.2, fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +fsevents@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -5149,12 +5178,14 @@ pretty-format@^3.8.0: resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew== -prisma@^4.16.2: - version "4.16.2" - resolved "https://registry.yarnpkg.com/prisma/-/prisma-4.16.2.tgz#469e0a0991c6ae5bcde289401726bb012253339e" - integrity sha512-SYCsBvDf0/7XSJyf2cHTLjLeTLVXYfqp7pG5eEVafFLeT0u/hLFz/9W196nDRGUOo1JfPatAEb+uEnTQImQC1g== +prisma@^5.20.0: + version "5.20.0" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.20.0.tgz#f2ab266a0d59383506886e7acbff0dbf322f4c7e" + integrity sha512-6obb3ucKgAnsGS9x9gLOe8qa51XxvJ3vLQtmyf52CTey1Qcez3A6W6ROH5HIz5Q5bW+0VpmZb8WBohieMFGpig== dependencies: - "@prisma/engines" "4.16.2" + "@prisma/engines" "5.20.0" + optionalDependencies: + fsevents "2.3.3" process@^0.11.10: version "0.11.10" From d1c3748681fe421dfa17d42ab2ff017950fcccea Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sun, 3 Nov 2024 03:34:21 -0500 Subject: [PATCH 02/33] minor improvement --- .env.sample | 1 - lib/api/controllers/users/postUser.ts | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.env.sample b/.env.sample index 775b05d7..c34fff22 100644 --- a/.env.sample +++ b/.env.sample @@ -36,7 +36,6 @@ PREVIEW_MAX_BUFFER= IMPORT_LIMIT= PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH= MAX_WORKERS= -DISABLE_INVITES= # AWS S3 Settings SPACES_KEY= diff --git a/lib/api/controllers/users/postUser.ts b/lib/api/controllers/users/postUser.ts index f77e3c07..b299a636 100644 --- a/lib/api/controllers/users/postUser.ts +++ b/lib/api/controllers/users/postUser.ts @@ -22,8 +22,6 @@ export default async function postUser( const isAdmin = parentUser && parentUser.id === Number(process.env.NEXT_PUBLIC_ADMIN || 1); - const DISABLE_INVITES = process.env.DISABLE_INVITES === "true"; - if (process.env.NEXT_PUBLIC_DISABLE_REGISTRATION === "true" && !isAdmin) { return { response: "Registration is disabled.", status: 400 }; } @@ -42,7 +40,7 @@ export default async function postUser( const { name, email, password, invite } = dataValidation.data; let { username } = dataValidation.data; - if (invite && (DISABLE_INVITES || !emailEnabled)) { + if (invite && (!stripeEnabled || !emailEnabled)) { return { response: "You are not authorized to invite users.", status: 401 }; } else if (invite && !parentUser) { return { response: "You must be logged in to invite users.", status: 401 }; From 0f5b70eda7484c0ff373d7379ce372cdfd108019 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sun, 3 Nov 2024 03:59:39 -0500 Subject: [PATCH 03/33] update prisma --- package.json | 14 ++++-- yarn.lock | 135 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 92 insertions(+), 57 deletions(-) diff --git a/package.json b/package.json index ab3d816e..dc199693 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "linkwarden", - "version": "v2.7.1", + "version": "v2.8.0", "main": "index.js", "repository": "https://github.com/linkwarden/linkwarden.git", "author": "Daniel31X13 ", @@ -25,7 +25,9 @@ "@aws-sdk/client-s3": "^3.379.1", "@headlessui/react": "^1.7.15", "@mozilla/readability": "^0.4.4", - "@prisma/client": "^5.20.0", + "@phosphor-icons/core": "^2.1.1", + "@phosphor-icons/react": "^2.1.7", + "@prisma/client": "^5.21.1", "@stripe/stripe-js": "^1.54.1", "@tanstack/react-query": "^5.51.15", "@tanstack/react-query-devtools": "^5.51.15", @@ -50,6 +52,7 @@ "eslint-config-next": "13.4.9", "formidable": "^3.5.1", "framer-motion": "^10.16.4", + "fuse.js": "^7.0.0", "handlebars": "^4.7.8", "himalaya": "^1.1.0", "i18next": "^23.11.5", @@ -76,7 +79,8 @@ "socks-proxy-agent": "^8.0.2", "stripe": "^12.13.0", "tailwind-merge": "^2.3.0", - "vaul": "^0.8.8", + "vaul": "^0.9.1", + "zod": "^3.23.8", "zustand": "^4.3.8" }, "devDependencies": { @@ -91,8 +95,8 @@ "nodemon": "^3.0.2", "postcss": "^8.4.26", "prettier": "3.1.1", - "prisma": "^5.20.0", - "tailwindcss": "^3.3.3", + "prisma": "^5.21.1", + "tailwindcss": "^3.4.10", "ts-node": "^10.9.2", "typescript": "4.9.4" } diff --git a/yarn.lock b/yarn.lock index c5362b54..e06adb4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1281,6 +1281,16 @@ resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d" integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA== +"@phosphor-icons/core@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@phosphor-icons/core/-/core-2.1.1.tgz#62a4cfbec9772f1a613a647da214fbb96f3ad39d" + integrity sha512-v4ARvrip4qBCImOE5rmPUylOEK4iiED9ZyKjcvzuezqMaiRASCHKcRIuvvxL/twvLpkfnEODCOJp5dM4eZilxQ== + +"@phosphor-icons/react@^2.1.7": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@phosphor-icons/react/-/react-2.1.7.tgz#b11a4b25849b7e3849970b688d9fe91e5d4fd8d7" + integrity sha512-g2e2eVAn1XG2a+LI09QU3IORLhnFNAFkNbo2iwbX6NOKSLOwvEMmTa7CgOzEbgNWR47z8i8kwjdvYZ5fkGx1mQ== + "@pkgr/utils@^2.3.1": version "2.3.1" resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.3.1.tgz#0a9b06ffddee364d6642b3cd562ca76f55b34a03" @@ -1300,46 +1310,46 @@ dependencies: playwright "1.45.0" -"@prisma/client@^5.20.0": - version "5.20.0" - resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.20.0.tgz#4fc9f2b2341c9c997c139df4445688dd6b39663b" - integrity sha512-CLv55ZuMuUawMsxoqxGtLT3bEZoa2W8L3Qnp6rDIFWy+ZBrUcOFKdoeGPSnbBqxc3SkdxJrF+D1veN/WNynZYA== +"@prisma/client@^5.21.1": + version "5.21.1" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.21.1.tgz#ad51ef220eb80173f882e859960d81e626b73898" + integrity sha512-3n+GgbAZYjaS/k0M03yQsQfR1APbr411r74foknnsGpmhNKBG49VuUkxIU6jORgvJPChoD4WC4PqoHImN1FP0w== -"@prisma/debug@5.20.0": - version "5.20.0" - resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.20.0.tgz#c6d1cf6e3c6e9dba150347f13ca200b1d66cc9fc" - integrity sha512-oCx79MJ4HSujokA8S1g0xgZUGybD4SyIOydoHMngFYiwEwYDQ5tBQkK5XoEHuwOYDKUOKRn/J0MEymckc4IgsQ== +"@prisma/debug@5.21.1": + version "5.21.1" + resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.21.1.tgz#df4383cb8a6273b1d6112cda0f1d5bef73e71be7" + integrity sha512-uY8SAhcnORhvgtOrNdvWS98Aq/nkQ9QDUxrWAgW8XrCZaI3j2X7zb7Xe6GQSh6xSesKffFbFlkw0c2luHQviZA== -"@prisma/engines-version@5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284": - version "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284" - resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284.tgz#9a53b13cdcfd706ae54198111000f33c63655c39" - integrity sha512-Lg8AS5lpi0auZe2Mn4gjuCg081UZf88k3cn0RCwHgR+6cyHHpttPZBElJTHf83ZGsRNAmVCZCfUGA57WB4u4JA== +"@prisma/engines-version@5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36": + version "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36.tgz#8a5f136a8ee71995bf635686bd2f1a6650f9320c" + integrity sha512-qvnEflL0//lh44S/T9NcvTMxfyowNeUxTunPcDfKPjyJNrCNf2F1zQLcUv5UHAruECpX+zz21CzsC7V2xAeM7Q== -"@prisma/engines@5.20.0": - version "5.20.0" - resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.20.0.tgz#86fe407e55219d33d03ebc26dc829a422faed545" - integrity sha512-DtqkP+hcZvPEbj8t8dK5df2b7d3B8GNauKqaddRRqQBBlgkbdhJkxhoJTrOowlS3vaRt2iMCkU0+CSNn0KhqAQ== +"@prisma/engines@5.21.1": + version "5.21.1" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.21.1.tgz#05f9bc50eb4aa169b31cadfb402165bd44e0653f" + integrity sha512-hGVTldUkIkTwoV8//hmnAAiAchi4oMEKD3aW5H2RrnI50tTdwza7VQbTTAyN3OIHWlK5DVg6xV7X8N/9dtOydA== dependencies: - "@prisma/debug" "5.20.0" - "@prisma/engines-version" "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284" - "@prisma/fetch-engine" "5.20.0" - "@prisma/get-platform" "5.20.0" + "@prisma/debug" "5.21.1" + "@prisma/engines-version" "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36" + "@prisma/fetch-engine" "5.21.1" + "@prisma/get-platform" "5.21.1" -"@prisma/fetch-engine@5.20.0": - version "5.20.0" - resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.20.0.tgz#b917880fb08f654981f14ca49923031b39683586" - integrity sha512-JVcaPXC940wOGpCOwuqQRTz6I9SaBK0c1BAyC1pcz9xBi+dzFgUu3G/p9GV1FhFs9OKpfSpIhQfUJE9y00zhqw== +"@prisma/fetch-engine@5.21.1": + version "5.21.1" + resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.21.1.tgz#c56008f954199a3f3f2183d892f093f64976e4d8" + integrity sha512-70S31vgpCGcp9J+mh/wHtLCkVezLUqe/fGWk3J3JWZIN7prdYSlr1C0niaWUyNK2VflLXYi8kMjAmSxUVq6WGQ== dependencies: - "@prisma/debug" "5.20.0" - "@prisma/engines-version" "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284" - "@prisma/get-platform" "5.20.0" + "@prisma/debug" "5.21.1" + "@prisma/engines-version" "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36" + "@prisma/get-platform" "5.21.1" -"@prisma/get-platform@5.20.0": - version "5.20.0" - resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.20.0.tgz#c1a53a8d8af67f2b4a6b97dd4d25b1c603236804" - integrity sha512-8/+CehTZZNzJlvuryRgc77hZCWrUDYd/PmlZ7p2yNXtmf2Una4BWnTbak3us6WVdqoz5wmptk6IhsXdG2v5fmA== +"@prisma/get-platform@5.21.1": + version "5.21.1" + resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.21.1.tgz#a2219e7755cec881dffc66469c31bb0975a95b54" + integrity sha512-sRxjL3Igst3ct+e8ya/x//cDXmpLbZQ5vfps2N4tWl4VGKQAmym77C/IG/psSMsQKszc8uFC/q1dgmKFLUgXZQ== dependencies: - "@prisma/debug" "5.20.0" + "@prisma/debug" "5.21.1" "@radix-ui/primitive@1.0.1": version "1.0.1" @@ -3393,7 +3403,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9: +fast-glob@^3.2.11, fast-glob@^3.2.9: version "3.2.12" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== @@ -3404,6 +3414,17 @@ fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -3582,6 +3603,11 @@ functions-have-names@^1.2.2: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +fuse.js@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-7.0.0.tgz#6573c9fcd4c8268e403b4fc7d7131ffcf99a9eb2" + integrity sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q== + gauge@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" @@ -4282,10 +4308,10 @@ jimp@^0.22.10: "@jimp/types" "^0.22.10" regenerator-runtime "^0.13.3" -jiti@^1.18.2: - version "1.18.2" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd" - integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg== +jiti@^1.21.0: + version "1.21.6" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" + integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== jose@^4.11.1, jose@^4.11.4, jose@^4.14.1: version "4.14.4" @@ -5178,12 +5204,12 @@ pretty-format@^3.8.0: resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew== -prisma@^5.20.0: - version "5.20.0" - resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.20.0.tgz#f2ab266a0d59383506886e7acbff0dbf322f4c7e" - integrity sha512-6obb3ucKgAnsGS9x9gLOe8qa51XxvJ3vLQtmyf52CTey1Qcez3A6W6ROH5HIz5Q5bW+0VpmZb8WBohieMFGpig== +prisma@^5.21.1: + version "5.21.1" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.21.1.tgz#3ffe4f4b60ea8df2e6d5f24f0cea090bcc5c0bd6" + integrity sha512-PB+Iqzld/uQBPaaw2UVIk84kb0ITsLajzsxzsadxxl54eaU5Gyl2/L02ysivHxK89t7YrfQJm+Ggk37uvM70oQ== dependencies: - "@prisma/engines" "5.20.0" + "@prisma/engines" "5.21.1" optionalDependencies: fsevents "2.3.3" @@ -5892,20 +5918,20 @@ tailwind-merge@^2.3.0: dependencies: "@babel/runtime" "^7.24.1" -tailwindcss@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.3.tgz#90da807393a2859189e48e9e7000e6880a736daf" - integrity sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w== +tailwindcss@^3.4.10: + version "3.4.10" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.10.tgz#70442d9aeb78758d1f911af29af8255ecdb8ffef" + integrity sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w== dependencies: "@alloc/quick-lru" "^5.2.0" arg "^5.0.2" chokidar "^3.5.3" didyoumean "^1.2.2" dlv "^1.1.3" - fast-glob "^3.2.12" + fast-glob "^3.3.0" glob-parent "^6.0.2" is-glob "^4.0.3" - jiti "^1.18.2" + jiti "^1.21.0" lilconfig "^2.1.0" micromatch "^4.0.5" normalize-path "^3.0.0" @@ -6270,10 +6296,10 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -vaul@^0.8.8: - version "0.8.8" - resolved "https://registry.yarnpkg.com/vaul/-/vaul-0.8.8.tgz#c5edc041825fdeaddf0a89e326abcc7ac7449a2d" - integrity sha512-Z9K2b90M/LtY/sRyM1yfA8Y4mHC/5WIqhO2u7Byr49r5LQXkLGdVXiehsnjtws9CL+DyknwTuRMJXlCOHTqg/g== +vaul@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/vaul/-/vaul-0.9.1.tgz#3640198e04636b209b1f907fcf3079bec6ecc66b" + integrity sha512-fAhd7i4RNMinx+WEm6pF3nOl78DFkAazcN04ElLPFF9BMCNGbY/kou8UMhIcicm0rJCNePJP0Yyza60gGOD0Jw== dependencies: "@radix-ui/react-dialog" "^1.0.4" @@ -6516,6 +6542,11 @@ zod@3.21.4: resolved "https://registry.yarnpkg.com/zod/-/zod-3.21.4.tgz#10882231d992519f0a10b5dd58a38c9dabbb64db" integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw== +zod@^3.23.8: + version "3.23.8" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" + integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== + zustand@^4.3.8: version "4.3.8" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.3.8.tgz#37113df8e9e1421b0be1b2dca02b49b76210e7c4" From a6a0f6965be41857db9129f4073ba12dc69f04cf Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Wed, 6 Nov 2024 03:36:02 -0500 Subject: [PATCH 04/33] bug fixed --- components/IconPopover.tsx | 13 ++-- lib/api/preservationScheme/handleMonolith.ts | 2 +- pages/preserved/[id].tsx | 74 ++++++++++---------- pages/public/preserved/[id].tsx | 66 +++++++++-------- public/locales/en/common.json | 3 +- 5 files changed, 84 insertions(+), 74 deletions(-) diff --git a/components/IconPopover.tsx b/components/IconPopover.tsx index cdbe8f62..878cc322 100644 --- a/components/IconPopover.tsx +++ b/components/IconPopover.tsx @@ -127,11 +127,14 @@ const IconPopover = ({ -
} - > - {t("reset_defaults")} +
+

{t("close_to_apply")}

+
} + > + {t("reset_defaults")} +
diff --git a/lib/api/preservationScheme/handleMonolith.ts b/lib/api/preservationScheme/handleMonolith.ts index f7c08f55..d00850cb 100644 --- a/lib/api/preservationScheme/handleMonolith.ts +++ b/lib/api/preservationScheme/handleMonolith.ts @@ -39,7 +39,7 @@ const handleMonolith = async (link: Link, content: string) => { }); }); } catch (err) { - console.log("Error running MONOLITH:", err); + console.log("Uncaught Monolith error..."); } }; diff --git a/pages/preserved/[id].tsx b/pages/preserved/[id].tsx index de216053..0259cb3a 100644 --- a/pages/preserved/[id].tsx +++ b/pages/preserved/[id].tsx @@ -1,70 +1,70 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect } from "react"; import { useRouter } from "next/router"; -import { - ArchivedFormat, - LinkIncludingShortenedCollectionAndTags, -} from "@/types/global"; +import { ArchivedFormat } from "@/types/global"; import ReadableView from "@/components/ReadableView"; import getServerSideProps from "@/lib/client/getServerSideProps"; -import { useGetLink, useLinks } from "@/hooks/store/links"; +import { useGetLink } from "@/hooks/store/links"; +import clsx from "clsx"; export default function Index() { - const { links } = useLinks(); - const getLink = useGetLink(); - const [link, setLink] = useState(); - const router = useRouter(); useEffect(() => { - const fetchLink = async () => { - if (router.query.id) { - await getLink.mutateAsync({ id: Number(router.query.id) }); - } - }; - - fetchLink(); + if (router.query.id) { + getLink.mutateAsync({ id: Number(router.query.id) }); + } }, []); - useEffect(() => { - if (links && links[0]) - setLink(links.find((e) => e.id === Number(router.query.id))); - }, [links]); - return ( -
+
{/*
Readable
*/} - {link && Number(router.query.format) === ArchivedFormat.readability && ( - - )} - {link && Number(router.query.format) === ArchivedFormat.monolith && ( + {getLink.data?.id && + Number(router.query.format) === ArchivedFormat.readability ? ( + + ) : getLink.data?.id && + Number(router.query.format) === ArchivedFormat.monolith ? ( - )} - {link && Number(router.query.format) === ArchivedFormat.pdf && ( + ) : getLink.data?.id && + Number(router.query.format) === ArchivedFormat.pdf ? ( - )} - {link && Number(router.query.format) === ArchivedFormat.png && ( + ) : getLink.data?.id && + Number(router.query.format) === ArchivedFormat.png ? ( - )} - {link && Number(router.query.format) === ArchivedFormat.jpeg && ( + ) : getLink.data?.id && + Number(router.query.format) === ArchivedFormat.jpeg ? ( + ) : getLink.error ? ( +

404 - Not found

+ ) : ( +
+
+
+
+
+
+
+
+
+
+
)}
); diff --git a/pages/public/preserved/[id].tsx b/pages/public/preserved/[id].tsx index 31544b0e..5d02df60 100644 --- a/pages/public/preserved/[id].tsx +++ b/pages/public/preserved/[id].tsx @@ -1,64 +1,70 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect } from "react"; import { useRouter } from "next/router"; -import { - ArchivedFormat, - LinkIncludingShortenedCollectionAndTags, -} from "@/types/global"; +import { ArchivedFormat } from "@/types/global"; import ReadableView from "@/components/ReadableView"; import getServerSideProps from "@/lib/client/getServerSideProps"; import { useGetLink } from "@/hooks/store/links"; +import clsx from "clsx"; export default function Index() { const getLink = useGetLink(); - const [link, setLink] = useState(); - const router = useRouter(); useEffect(() => { - const fetchLink = async () => { - if (router.query.id) { - const get = await getLink.mutateAsync({ id: Number(router.query.id) }); - setLink(get); - } - }; - - fetchLink(); + if (router.query.id) { + getLink.mutateAsync({ id: Number(router.query.id), isPublicRoute: true }); + } }, []); return ( -
+
{/*
Readable
*/} - {link && Number(router.query.format) === ArchivedFormat.readability && ( - - )} - {link && Number(router.query.format) === ArchivedFormat.monolith && ( + {getLink.data?.id && + Number(router.query.format) === ArchivedFormat.readability ? ( + + ) : getLink.data?.id && + Number(router.query.format) === ArchivedFormat.monolith ? ( - )} - {link && Number(router.query.format) === ArchivedFormat.pdf && ( + ) : getLink.data?.id && + Number(router.query.format) === ArchivedFormat.pdf ? ( - )} - {link && Number(router.query.format) === ArchivedFormat.png && ( + ) : getLink.data?.id && + Number(router.query.format) === ArchivedFormat.png ? ( - )} - {link && Number(router.query.format) === ArchivedFormat.jpeg && ( + ) : getLink.data?.id && + Number(router.query.format) === ArchivedFormat.jpeg ? ( + ) : getLink.error ? ( +

404 - Not found

+ ) : ( +
+
+
+
+
+
+
+
+
+
+
)}
); diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 16f4d124..3334acc5 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -416,5 +416,6 @@ "resend_invite_success": "Invitation Resent!", "remove_user": "Remove User", "continue_to_dashboard": "Continue to Dashboard", - "confirm_user_removal_desc": "They will need to have a subscription to access Linkwarden again." + "confirm_user_removal_desc": "They will need to have a subscription to access Linkwarden again.", + "close_to_apply": "Close to apply" } \ No newline at end of file From ac8add8c5d801a621270165633eed79199bd3ddd Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Wed, 6 Nov 2024 22:53:21 -0500 Subject: [PATCH 05/33] small improvement --- components/IconPopover.tsx | 184 +++++++++++++++++----------------- public/locales/en/common.json | 2 +- 2 files changed, 94 insertions(+), 92 deletions(-) diff --git a/components/IconPopover.tsx b/components/IconPopover.tsx index 878cc322..6b13d211 100644 --- a/components/IconPopover.tsx +++ b/components/IconPopover.tsx @@ -39,103 +39,105 @@ const IconPopover = ({ onClose={() => onClose()} className={clsx( className, - "fade-in bg-base-200 border border-neutral-content p-2 w-[22.5rem] rounded-lg shadow-md" + "fade-in bg-base-200 border border-neutral-content p-3 w-[22.5rem] rounded-lg shadow-md" )} > -
-
- setQuery(e.target.value)} +
+ setQuery(e.target.value)} + /> + +
+ +
+ +
+ setColor(e)} + className="border border-neutral-content rounded-lg" /> -
- +
+ + + + + +
- -
- setColor(e)} /> - -
- - - - - - -
-
-
-

{t("close_to_apply")}

-
} - > - {t("reset_defaults")} -
+
+
+
} + > + {t("reset_defaults")}
+

{t("click_out_to_apply")}

diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 3334acc5..936059d7 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -417,5 +417,5 @@ "remove_user": "Remove User", "continue_to_dashboard": "Continue to Dashboard", "confirm_user_removal_desc": "They will need to have a subscription to access Linkwarden again.", - "close_to_apply": "Close to apply" + "click_out_to_apply": "Click outside to apply" } \ No newline at end of file From ac3888f9b34a9e9e9d0e4bca66308eb0ec293338 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Wed, 6 Nov 2024 23:57:20 -0500 Subject: [PATCH 06/33] icon picker is now much more efficient --- components/IconGrid.tsx | 83 +++++++++++++++++++++++++++++++---------- package.json | 2 + yarn.lock | 17 ++++++++- 3 files changed, 81 insertions(+), 21 deletions(-) diff --git a/components/IconGrid.tsx b/components/IconGrid.tsx index b6333a72..494337e3 100644 --- a/components/IconGrid.tsx +++ b/components/IconGrid.tsx @@ -1,6 +1,7 @@ import { icons } from "@/lib/client/icons"; import Fuse from "fuse.js"; -import { useMemo } from "react"; +import { forwardRef, useMemo } from "react"; +import { FixedSizeGrid as Grid } from "react-window"; const fuse = new Fuse(icons, { keys: [{ name: "name", weight: 4 }, "tags", "categories"], @@ -17,32 +18,74 @@ type Props = { }; const IconGrid = ({ query, color, weight, iconName, setIconName }: Props) => { - const filteredQueryResultsSelector = useMemo(() => { + // Memoize the filtered results to avoid recalculations on each render + const filteredIcons = useMemo(() => { if (!query) { return icons; } return fuse.search(query).map((result) => result.item); }, [query]); + // Grid configuration + const columnCount = 6; + const rowCount = Math.ceil(filteredIcons.length / columnCount); + const GUTTER_SIZE = 5; + + // Render a single cell (icon) in the grid + const Cell = ({ columnIndex, rowIndex, style }: any) => { + const index = rowIndex * columnCount + columnIndex; + if (index >= filteredIcons.length) return null; // Prevent overflow + + const icon = filteredIcons[index]; + const IconComponent = icon.Icon; + + return ( +
setIconName(icon.pascal_name)} + className={`cursor-pointer p-[6px] rounded-lg bg-base-100 w-full ${ + icon.pascal_name === iconName + ? "outline outline-1 outline-primary" + : "" + }`} + > + +
+ ); + }; + + const innerElementType = forwardRef(({ style, ...rest }: any, ref) => ( +
+ )); + return ( - <> - {filteredQueryResultsSelector.map((icon) => { - const IconComponent = icon.Icon; - return ( -
setIconName(icon.pascal_name)} - className={`cursor-pointer btn p-1 box-border bg-base-100 border-none w-full ${ - icon.pascal_name === iconName - ? "outline outline-1 outline-primary" - : "" - }`} - > - -
- ); - })} - + + {Cell} + ); }; diff --git a/package.json b/package.json index dc199693..b07bbb2b 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "react-masonry-css": "^1.0.16", "react-select": "^5.7.4", "react-spinners": "^0.14.1", + "react-window": "^1.8.10", "socks-proxy-agent": "^8.0.2", "stripe": "^12.13.0", "tailwind-merge": "^2.3.0", @@ -89,6 +90,7 @@ "@types/dompurify": "^3.0.4", "@types/jsdom": "^21.1.3", "@types/node-fetch": "^2.6.10", + "@types/react-window": "^1.8.8", "@types/shelljs": "^0.8.15", "autoprefixer": "^10.4.14", "daisyui": "^4.4.2", diff --git a/yarn.lock b/yarn.lock index e06adb4f..fdf66a1b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2118,6 +2118,13 @@ dependencies: "@types/react" "*" +"@types/react-window@^1.8.8": + version "1.8.8" + resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.8.tgz#c20645414d142364fbe735818e1c1e0a145696e3" + integrity sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@18.2.14": version "18.2.14" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.14.tgz#fa7a6fecf1ce35ca94e74874f70c56ce88f7a127" @@ -4516,7 +4523,7 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -memoize-one@^5.0.4: +"memoize-one@>=3.1.1 <6", memoize-one@^5.0.4: version "5.2.1" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== @@ -5421,6 +5428,14 @@ react-transition-group@^4.3.0: loose-envify "^1.4.0" prop-types "^15.6.2" +react-window@^1.8.10: + version "1.8.10" + resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.10.tgz#9e6b08548316814b443f7002b1cf8fd3a1bdde03" + integrity sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg== + dependencies: + "@babel/runtime" "^7.0.0" + memoize-one ">=3.1.1 <6" + react@18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" From 7931e2d7b6f1d54949e1e0ec0e9107551a0bd166 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Thu, 7 Nov 2024 00:19:12 -0500 Subject: [PATCH 07/33] better logic when showing link icons --- .../LinkViews/LinkComponents/LinkIcon.tsx | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/components/LinkViews/LinkComponents/LinkIcon.tsx b/components/LinkViews/LinkComponents/LinkIcon.tsx index c423aa7e..327e7af3 100644 --- a/components/LinkViews/LinkComponents/LinkIcon.tsx +++ b/components/LinkViews/LinkComponents/LinkIcon.tsx @@ -1,7 +1,7 @@ import { LinkIncludingShortenedCollectionAndTags } from "@/types/global"; import Image from "next/image"; import isValidUrl from "@/lib/shared/isValidUrl"; -import React from "react"; +import React, { useState } from "react"; import Icon from "@/components/Icon"; import { IconWeight } from "@phosphor-icons/react"; import clsx from "clsx"; @@ -26,7 +26,7 @@ export default function LinkIcon({ const url = isValidUrl(link.url || "") && link.url ? new URL(link.url) : undefined; - const [showFavicon, setShowFavicon] = React.useState(true); + const [faviconLoaded, setFaviconLoaded] = useState(false); return (
onClick && onClick()}> @@ -41,21 +41,27 @@ export default function LinkIcon({ />
) : link.type === "url" && url ? ( - showFavicon ? ( + <> { - setShowFavicon(false); - }} + onLoadingComplete={() => setFaviconLoaded(true)} + onError={() => setFaviconLoaded(false)} /> - ) : ( - - ) + {!faviconLoaded && ( + + )} + ) : link.type === "pdf" ? ( Date: Thu, 7 Nov 2024 00:20:57 -0500 Subject: [PATCH 08/33] bug fixed --- components/ViewDropdown.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/components/ViewDropdown.tsx b/components/ViewDropdown.tsx index fdcd2af2..3726264d 100644 --- a/components/ViewDropdown.tsx +++ b/components/ViewDropdown.tsx @@ -90,11 +90,8 @@ export default function ViewDropdown({ viewMode, setViewMode }: Props) {

{t("show")}

{Object.entries(settings.show) .filter((e) => - settings.viewMode === ViewMode.List // Hide tags, image, icon, and description checkboxes in list view - ? e[0] !== "tags" && - e[0] !== "image" && - e[0] !== "icon" && - e[0] !== "description" + settings.viewMode === ViewMode.List // Hide tags, image, and description checkboxes in list view + ? e[0] !== "tags" && e[0] !== "image" && e[0] !== "description" : settings.viewMode === ViewMode.Card // Hide tags and description checkboxes in card view ? e[0] !== "tags" && e[0] !== "description" : true From 736e98ac7d0bcf22e38e4d2e488174bfb132fbb6 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Thu, 7 Nov 2024 01:12:05 -0500 Subject: [PATCH 09/33] improvements --- components/LinkDetails.tsx | 106 +++++--- .../LinkViews/LinkComponents/LinkActions.tsx | 18 +- .../LinkViews/LinkComponents/LinkCard.tsx | 4 +- .../LinkComponents/LinkCollection.tsx | 4 +- .../LinkViews/LinkComponents/LinkList.tsx | 6 +- .../LinkViews/LinkComponents/LinkMasonry.tsx | 7 +- components/ModalContent/LinkModal.tsx | 143 +++++----- package.json | 2 +- public/locales/de/common.json | 2 +- public/locales/en/common.json | 2 +- public/locales/es/common.json | 2 +- public/locales/fr/common.json | 2 +- public/locales/it/common.json | 2 +- public/locales/ja/common.json | 2 +- public/locales/nl/common.json | 2 +- public/locales/pt-BR/common.json | 2 +- public/locales/tr/common.json | 2 +- public/locales/uk/common.json | 2 +- public/locales/zh-TW/common.json | 2 +- public/locales/zh/common.json | 2 +- yarn.lock | 244 ++++++++---------- 21 files changed, 277 insertions(+), 281 deletions(-) diff --git a/components/LinkDetails.tsx b/components/LinkDetails.tsx index e7450553..9139f8be 100644 --- a/components/LinkDetails.tsx +++ b/components/LinkDetails.tsx @@ -42,6 +42,7 @@ type Props = { standalone?: boolean; mode?: "view" | "edit"; setMode?: Function; + onUpdateArchive?: Function; }; export default function LinkDetails({ @@ -50,6 +51,7 @@ export default function LinkDetails({ standalone, mode = "view", setMode, + onUpdateArchive, }: Props) { const [link, setLink] = useState(activeLink); @@ -236,46 +238,50 @@ export default function LinkDetails({
)} - {!standalone && (permissions === true || permissions?.canUpdate) && ( -
- +
+ )}
- {!standalone && (permissions === true || permissions?.canUpdate) ? ( + {!standalone && + (permissions === true || permissions?.canUpdate) && + !isPublicRoute ? (

-

- {link.url ? t("preserved_formats") : t("file")} -

+
+

+ {link.url ? t("preserved_formats") : t("file")} +

+ + {onUpdateArchive && + (permissions === true || permissions?.canUpdate) && + !isPublicRoute && ( +
+ +
+ )} +
{monolithAvailable(link) ? ( diff --git a/components/LinkViews/LinkComponents/LinkActions.tsx b/components/LinkViews/LinkComponents/LinkActions.tsx index e444f18f..ac162251 100644 --- a/components/LinkViews/LinkComponents/LinkActions.tsx +++ b/components/LinkViews/LinkComponents/LinkActions.tsx @@ -64,7 +64,7 @@ export default function LinkActions({ link, btnStyle }: Props) { onClick={() => setLinkModal(true)} >
- +
) : ( @@ -127,22 +127,6 @@ export default function LinkActions({ link, btnStyle }: Props) {
)} - {link.type === "url" && - (permissions === true || permissions?.canUpdate) && ( -
  • -
    { - (document?.activeElement as HTMLElement)?.blur(); - updateArchive(); - }} - className="whitespace-nowrap" - > - {t("refresh_preserved_formats")} -
    -
  • - )} {(permissions === true || permissions?.canDelete) && (
  • - + {!isPublicRoute && }
  • ); } diff --git a/components/LinkViews/LinkComponents/LinkCollection.tsx b/components/LinkViews/LinkComponents/LinkCollection.tsx index f416ede6..fdc29397 100644 --- a/components/LinkViews/LinkComponents/LinkCollection.tsx +++ b/components/LinkViews/LinkComponents/LinkCollection.tsx @@ -14,7 +14,7 @@ export default function LinkCollection({ link: LinkIncludingShortenedCollectionAndTags; collection: CollectionIncludingMembersAndLinkCount; }) { - return ( + return collection?.name ? ( <> {collection?.name}

    + ) : ( + <> ); } diff --git a/components/LinkViews/LinkComponents/LinkList.tsx b/components/LinkViews/LinkComponents/LinkList.tsx index b43c5957..3b4e46b3 100644 --- a/components/LinkViews/LinkComponents/LinkList.tsx +++ b/components/LinkViews/LinkComponents/LinkList.tsx @@ -20,6 +20,7 @@ import { useUser } from "@/hooks/store/user"; import { useLinks } from "@/hooks/store/links"; import useLocalSettingsStore from "@/store/localSettings"; import LinkPin from "./LinkPin"; +import { useRouter } from "next/router"; type Props = { link: LinkIncludingShortenedCollectionAndTags; @@ -91,6 +92,9 @@ export default function LinkCardCompact({ link, editMode }: Props) { editMode && (permissions === true || permissions?.canCreate || permissions?.canDelete); + const router = useRouter(); + + let isPublic = router.pathname.startsWith("/public") ? true : undefined; return ( <>
    - + {!isPublic && }
    diff --git a/components/LinkViews/LinkComponents/LinkMasonry.tsx b/components/LinkViews/LinkComponents/LinkMasonry.tsx index 529e46ed..eba17792 100644 --- a/components/LinkViews/LinkComponents/LinkMasonry.tsx +++ b/components/LinkViews/LinkComponents/LinkMasonry.tsx @@ -25,6 +25,7 @@ import { useGetLink, useLinks } from "@/hooks/store/links"; import useLocalSettingsStore from "@/store/localSettings"; import clsx from "clsx"; import LinkPin from "./LinkPin"; +import { useRouter } from "next/router"; type Props = { link: LinkIncludingShortenedCollectionAndTags; @@ -108,6 +109,10 @@ export default function LinkMasonry({ link, editMode, columns }: Props) { const isVisible = useOnScreen(ref); const permissions = usePermissions(collection?.id as number); + const router = useRouter(); + + let isPublic = router.pathname.startsWith("/public") ? true : undefined; + useEffect(() => { let interval: NodeJS.Timeout | null = null; @@ -241,7 +246,7 @@ export default function LinkMasonry({ link, editMode, columns }: Props) { {/* Overlay on hover */}
    - + {!isPublic && }
    ); } diff --git a/components/ModalContent/LinkModal.tsx b/components/ModalContent/LinkModal.tsx index 41b742e8..c3793ac1 100644 --- a/components/ModalContent/LinkModal.tsx +++ b/components/ModalContent/LinkModal.tsx @@ -51,7 +51,7 @@ export default function LinkModal({ onClick={() => onClose()} >
    - {(permissions === true || permissions?.canUpdate) && ( + {(permissions === true || permissions?.canUpdate) && !isPublicRoute && (
    -
    -
    - -
    -
      - { -
    • -
      { - (document?.activeElement as HTMLElement)?.blur(); - onPin(); - }} - className="whitespace-nowrap" - > - {link?.pinnedBy && link.pinnedBy[0] - ? t("unpin") - : t("pin_to_dashboard")} -
      -
    • - } - {link.type === "url" && - (permissions === true || permissions?.canUpdate) && ( + {!isPublicRoute && ( +
      +
      + +
      +
        + {
      • { (document?.activeElement as HTMLElement)?.blur(); - onUpdateArchive(); + onPin(); }} className="whitespace-nowrap" > - {t("refresh_preserved_formats")} + {link?.pinnedBy && link.pinnedBy[0] + ? t("unpin") + : t("pin_to_dashboard")} +
        +
      • + } + {link.type === "url" && + (permissions === true || permissions?.canUpdate) && ( +
      • +
        { + (document?.activeElement as HTMLElement)?.blur(); + onUpdateArchive(); + }} + className="whitespace-nowrap" + > + {t("refresh_preserved_formats")} +
        +
      • + )} + {(permissions === true || permissions?.canDelete) && ( +
      • +
        { + (document?.activeElement as HTMLElement)?.blur(); + console.log(e.shiftKey); + if (e.shiftKey) { + const load = toast.loading(t("deleting")); + + await deleteLink.mutateAsync(link.id as number, { + onSettled: (data, error) => { + toast.dismiss(load); + + if (error) { + toast.error(error.message); + } else { + toast.success(t("deleted")); + } + }, + }); + onClose(); + } else { + onDelete(); + onClose(); + } + }} + className="whitespace-nowrap" + > + {t("delete")}
      • )} - {(permissions === true || permissions?.canDelete) && ( -
      • -
        { - (document?.activeElement as HTMLElement)?.blur(); - console.log(e.shiftKey); - if (e.shiftKey) { - const load = toast.loading(t("deleting")); - - await deleteLink.mutateAsync(link.id as number, { - onSettled: (data, error) => { - toast.dismiss(load); - - if (error) { - toast.error(error.message); - } else { - toast.success(t("deleted")); - } - }, - }); - onClose(); - } else { - onDelete(); - onClose(); - } - }} - className="whitespace-nowrap" - > - {t("delete")} -
        -
      • - )} -
      -
      +
    +
    + )} {link.url && ( setMode(mode)} + onUpdateArchive={onUpdateArchive} />
    diff --git a/package.json b/package.json index b07bbb2b..b82f6b55 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "socks-proxy-agent": "^8.0.2", "stripe": "^12.13.0", "tailwind-merge": "^2.3.0", - "vaul": "^0.9.1", + "vaul": "^1.1.1", "zod": "^3.23.8", "zustand": "^4.3.8" }, diff --git a/public/locales/de/common.json b/public/locales/de/common.json index a35c6c8f..b26dbf48 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -256,7 +256,7 @@ "sending_request": "Anfrage senden...", "link_being_archived": "Link wird archiviert...", "preserved_formats": "Konservierte Formate", - "available_formats": "Die folgenden Formate sind für diesen Link verfügbar:", + "available_formats": "Die folgenden Formate sind für diesen Link verfügbar", "readable": "Leseansicht", "preservation_in_queue": "Linkkonservierung ist in der Warteschlange", "view_latest_snapshot": "Aktuellen Schnappschuss auf archive.org ansehen", diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 936059d7..33f9cfa7 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -256,7 +256,7 @@ "sending_request": "Sending request...", "link_being_archived": "Link is being archived...", "preserved_formats": "Preserved Formats", - "available_formats": "The following formats are available for this link:", + "available_formats": "The following formats are available for this link", "readable": "Readable", "preservation_in_queue": "Link preservation is in the queue", "view_latest_snapshot": "View latest snapshot on archive.org", diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 320d3a54..192ed65c 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -255,7 +255,7 @@ "sending_request": "Enviando solicitud...", "link_being_archived": "El enlace está siendo archivado...", "preserved_formats": "Formatos conservados", - "available_formats": "Los siguientes formatos están disponibles para este enlace:", + "available_formats": "Los siguientes formatos están disponibles para este enlace", "readable": "Versión lectura", "preservation_in_queue": "La conservación del enlace está en la cola.", "view_latest_snapshot": "Ver la última captura en archive.org", diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json index eb789b00..733341f8 100644 --- a/public/locales/fr/common.json +++ b/public/locales/fr/common.json @@ -255,7 +255,7 @@ "sending_request": "Envoi de la demande...", "link_being_archived": "Le lien est en cours d'archivage...", "preserved_formats": "Formats conservés", - "available_formats": "Les formats suivants sont disponibles pour ce lien:", + "available_formats": "Les formats suivants sont disponibles pour ce lien", "readable": "Lisible", "preservation_in_queue": "La préservation du lien est dans la file d'attente", "view_latest_snapshot": "Voir le dernier instantané sur archive.org", diff --git a/public/locales/it/common.json b/public/locales/it/common.json index e3ae5337..3e9543b9 100644 --- a/public/locales/it/common.json +++ b/public/locales/it/common.json @@ -256,7 +256,7 @@ "sending_request": "Invio richiesta...", "link_being_archived": "Il Link è in fase di archiviazione...", "preserved_formats": "Formati Preservati", - "available_formats": "I seguenti formati sono disponibili per questo link:", + "available_formats": "I seguenti formati sono disponibili per questo link", "readable": "Leggibile", "preservation_in_queue": "La preservazione del Link è in coda", "view_latest_snapshot": "Visualizza l'ultimo snapshot su archive.org", diff --git a/public/locales/ja/common.json b/public/locales/ja/common.json index dfc8c337..2dfae1ea 100644 --- a/public/locales/ja/common.json +++ b/public/locales/ja/common.json @@ -256,7 +256,7 @@ "sending_request": "リクエストを送信中...", "link_being_archived": "リンクがアーカイブされています...", "preserved_formats": "保存された形式", - "available_formats": "このリンクには以下の形式が利用可能です:", + "available_formats": "このリンクには以下の形式が利用可能です", "readable": "リーダブル", "preservation_in_queue": "リンクの保存がキューに追加されています", "view_latest_snapshot": "archive.org で最新のスナップショットを見る", diff --git a/public/locales/nl/common.json b/public/locales/nl/common.json index a1d38005..debb65cd 100644 --- a/public/locales/nl/common.json +++ b/public/locales/nl/common.json @@ -255,7 +255,7 @@ "sending_request": "Verzoek Verzenden...", "link_being_archived": "Link wordt gearchiveerd...", "preserved_formats": "Bewaarde Formaten", - "available_formats": "De volgende formaten zijn beschikbaar voor deze link:", + "available_formats": "De volgende formaten zijn beschikbaar voor deze link", "readable": "Leesbaar", "preservation_in_queue": "Linkbewaring staat in de wachtrij", "view_latest_snapshot": "Bekijk de laatste momentopname op archive.org", diff --git a/public/locales/pt-BR/common.json b/public/locales/pt-BR/common.json index 80c77141..c5509c78 100644 --- a/public/locales/pt-BR/common.json +++ b/public/locales/pt-BR/common.json @@ -272,7 +272,7 @@ "sending_request": "Enviando solicitação...", "link_being_archived": "O link está sendo arquivado...", "preserved_formats": "Formatos Preservados", - "available_formats": "Os seguintes formatos estão disponíveis para este link:", + "available_formats": "Os seguintes formatos estão disponíveis para este link", "readable": "Legível", "preservation_in_queue": "A preservação do link está na fila", "view_latest_snapshot": "Ver o último snapshot em archive.org", diff --git a/public/locales/tr/common.json b/public/locales/tr/common.json index 2cc4ef2d..304d3869 100644 --- a/public/locales/tr/common.json +++ b/public/locales/tr/common.json @@ -257,7 +257,7 @@ "sending_request": "İstek Gönderiliyor...", "link_being_archived": "Bağlantı arşivleniyor...", "preserved_formats": "Korunan Formatlar", - "available_formats": "Bu bağlantı için kullanılabilir formatlar:", + "available_formats": "Bu bağlantı için kullanılabilir formatlar", "readable": "Okunabilir", "preservation_in_queue": "Bağlantı koruma sırada", "view_latest_snapshot": "archive.org'da son anlık görüntüyü görüntüle", diff --git a/public/locales/uk/common.json b/public/locales/uk/common.json index a88a1bf1..287a4575 100644 --- a/public/locales/uk/common.json +++ b/public/locales/uk/common.json @@ -256,7 +256,7 @@ "sending_request": "Надсилання запиту...", "link_being_archived": "Посилання архівується...", "preserved_formats": "Збережені формати", - "available_formats": "Для цього посилання доступні такі формати:", + "available_formats": "Для цього посилання доступні такі формати", "readable": "Читабельний", "preservation_in_queue": "У черзі збереження посилання", "view_latest_snapshot": "Перегляньте останній знімок на archive.org", diff --git a/public/locales/zh-TW/common.json b/public/locales/zh-TW/common.json index d3efefc9..30a2db32 100644 --- a/public/locales/zh-TW/common.json +++ b/public/locales/zh-TW/common.json @@ -255,7 +255,7 @@ "sending_request": "正在發送請求...", "link_being_archived": "連結正在封存...", "preserved_formats": "保存格式", - "available_formats": "以下格式可用於此連結:", + "available_formats": "以下格式可用於此連結", "readable": "可讀視圖", "preservation_in_queue": "連結保存正在處理中...", "view_latest_snapshot": "在 archive.org 上查看最新快照", diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json index b5b7977b..3b554d9f 100644 --- a/public/locales/zh/common.json +++ b/public/locales/zh/common.json @@ -255,7 +255,7 @@ "sending_request": "正在发送请求...", "link_being_archived": "链接正在归档...", "preserved_formats": "保存格式", - "available_formats": "以下格式可用于此链接:", + "available_formats": "以下格式可用于此链接", "readable": "可读视图", "preservation_in_queue": "链接保存正在处理中...", "view_latest_snapshot": "在 archive.org 上查看最新快照", diff --git a/yarn.lock b/yarn.lock index fdf66a1b..71ba16b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -645,13 +645,6 @@ dependencies: regenerator-runtime "^0.13.11" -"@babel/runtime@^7.13.10": - version "7.23.8" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.8.tgz#8ee6fe1ac47add7122902f257b8ddf55c898f650" - integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw== - dependencies: - regenerator-runtime "^0.14.0" - "@babel/runtime@^7.15.4", "@babel/runtime@^7.9.2": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" @@ -1351,147 +1344,126 @@ dependencies: "@prisma/debug" "5.21.1" -"@radix-ui/primitive@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd" - integrity sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw== - dependencies: - "@babel/runtime" "^7.13.10" +"@radix-ui/primitive@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.0.tgz#42ef83b3b56dccad5d703ae8c42919a68798bbe2" + integrity sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA== -"@radix-ui/react-compose-refs@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989" - integrity sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw== - dependencies: - "@babel/runtime" "^7.13.10" +"@radix-ui/react-compose-refs@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz#656432461fc8283d7b591dcf0d79152fae9ecc74" + integrity sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw== -"@radix-ui/react-context@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c" - integrity sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg== - dependencies: - "@babel/runtime" "^7.13.10" +"@radix-ui/react-context@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.1.tgz#82074aa83a472353bb22e86f11bcbd1c61c4c71a" + integrity sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q== -"@radix-ui/react-dialog@^1.0.4": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300" - integrity sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q== +"@radix-ui/react-dialog@^1.1.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.1.2.tgz#d9345575211d6f2d13e209e84aec9a8584b54d6c" + integrity sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-dismissable-layer" "1.0.5" - "@radix-ui/react-focus-guards" "1.0.1" - "@radix-ui/react-focus-scope" "1.0.4" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-portal" "1.0.4" - "@radix-ui/react-presence" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-slot" "1.0.2" - "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.1" + "@radix-ui/react-dismissable-layer" "1.1.1" + "@radix-ui/react-focus-guards" "1.1.1" + "@radix-ui/react-focus-scope" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-portal" "1.1.2" + "@radix-ui/react-presence" "1.1.1" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-slot" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" aria-hidden "^1.1.1" - react-remove-scroll "2.5.5" + react-remove-scroll "2.6.0" -"@radix-ui/react-dismissable-layer@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4" - integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g== +"@radix-ui/react-dismissable-layer@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz#cbdcb739c5403382bdde5f9243042ba643883396" + integrity sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-callback-ref" "1.0.1" - "@radix-ui/react-use-escape-keydown" "1.0.3" + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-use-escape-keydown" "1.1.0" -"@radix-ui/react-focus-guards@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad" - integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA== - dependencies: - "@babel/runtime" "^7.13.10" +"@radix-ui/react-focus-guards@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz#8635edd346304f8b42cae86b05912b61aef27afe" + integrity sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg== -"@radix-ui/react-focus-scope@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525" - integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA== +"@radix-ui/react-focus-scope@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz#ebe2891a298e0a33ad34daab2aad8dea31caf0b2" + integrity sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" -"@radix-ui/react-id@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0" - integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ== +"@radix-ui/react-id@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.0.tgz#de47339656594ad722eb87f94a6b25f9cffae0ed" + integrity sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-layout-effect" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.1.0" -"@radix-ui/react-portal@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15" - integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q== +"@radix-ui/react-portal@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.2.tgz#51eb46dae7505074b306ebcb985bf65cc547d74e" + integrity sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-layout-effect" "1.1.0" -"@radix-ui/react-presence@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba" - integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg== +"@radix-ui/react-presence@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.1.tgz#98aba423dba5e0c687a782c0669dcd99de17f9b1" + integrity sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-use-layout-effect" "1.0.1" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-use-layout-effect" "1.1.0" -"@radix-ui/react-primitive@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0" - integrity sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g== +"@radix-ui/react-primitive@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz#fe05715faa9203a223ccc0be15dc44b9f9822884" + integrity sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-slot" "1.1.0" -"@radix-ui/react-slot@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.2.tgz#a9ff4423eade67f501ffb32ec22064bc9d3099ab" - integrity sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg== +"@radix-ui/react-slot@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.0.tgz#7c5e48c36ef5496d97b08f1357bb26ed7c714b84" + integrity sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-compose-refs" "1.1.0" -"@radix-ui/react-use-callback-ref@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a" - integrity sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ== - dependencies: - "@babel/runtime" "^7.13.10" +"@radix-ui/react-use-callback-ref@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1" + integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw== -"@radix-ui/react-use-controllable-state@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286" - integrity sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA== +"@radix-ui/react-use-controllable-state@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz#1321446857bb786917df54c0d4d084877aab04b0" + integrity sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-callback-ref" "1.1.0" -"@radix-ui/react-use-escape-keydown@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755" - integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg== +"@radix-ui/react-use-escape-keydown@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz#31a5b87c3b726504b74e05dac1edce7437b98754" + integrity sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-callback-ref" "1.1.0" -"@radix-ui/react-use-layout-effect@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399" - integrity sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ== - dependencies: - "@babel/runtime" "^7.13.10" +"@radix-ui/react-use-layout-effect@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz#3c2c8ce04827b26a39e442ff4888d9212268bd27" + integrity sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w== "@rushstack/eslint-patch@^1.1.3": version "1.2.0" @@ -5370,20 +5342,20 @@ react-redux@^7.0.3: prop-types "^15.7.2" react-is "^17.0.2" -react-remove-scroll-bar@^2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9" - integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A== +react-remove-scroll-bar@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c" + integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g== dependencies: react-style-singleton "^2.2.1" tslib "^2.0.0" -react-remove-scroll@2.5.5: - version "2.5.5" - resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77" - integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw== +react-remove-scroll@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz#fb03a0845d7768a4f1519a99fdb84983b793dc07" + integrity sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ== dependencies: - react-remove-scroll-bar "^2.3.3" + react-remove-scroll-bar "^2.3.6" react-style-singleton "^2.2.1" tslib "^2.1.0" use-callback-ref "^1.3.0" @@ -6311,12 +6283,12 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -vaul@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/vaul/-/vaul-0.9.1.tgz#3640198e04636b209b1f907fcf3079bec6ecc66b" - integrity sha512-fAhd7i4RNMinx+WEm6pF3nOl78DFkAazcN04ElLPFF9BMCNGbY/kou8UMhIcicm0rJCNePJP0Yyza60gGOD0Jw== +vaul@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/vaul/-/vaul-1.1.1.tgz#93aceaad16f7c53aacf28a2609b2dd43b5a91fa0" + integrity sha512-+ejzF6ffQKPcfgS7uOrGn017g39F8SO4yLPXbBhpC7a0H+oPqPna8f1BUfXaz8eU4+pxbQcmjxW+jWBSbxjaFg== dependencies: - "@radix-ui/react-dialog" "^1.0.4" + "@radix-ui/react-dialog" "^1.1.1" verror@1.10.0: version "1.10.0" From d5602a09cd8222a12e1b82950ef22252f0e6e04d Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Thu, 7 Nov 2024 01:14:23 -0500 Subject: [PATCH 10/33] minor fix --- components/InputSelect/styles.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/components/InputSelect/styles.ts b/components/InputSelect/styles.ts index f05f4a51..6018a512 100644 --- a/components/InputSelect/styles.ts +++ b/components/InputSelect/styles.ts @@ -31,6 +31,7 @@ export const styles: StylesConfig = { height: "full", borderRadius: "0.375rem", lineHeight: "1.25rem", + zIndex: 10, // "@media screen and (min-width: 1024px)": { // fontSize: "0.875rem", // }, From cc45c8fc3ee2f44b8f55f4a6095e405006fc099f Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Thu, 7 Nov 2024 01:17:30 -0500 Subject: [PATCH 11/33] minor improvement --- .../EditCollectionSharingModal.tsx | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/components/ModalContent/EditCollectionSharingModal.tsx b/components/ModalContent/EditCollectionSharingModal.tsx index ba7bfddc..6a6beeb2 100644 --- a/components/ModalContent/EditCollectionSharingModal.tsx +++ b/components/ModalContent/EditCollectionSharingModal.tsx @@ -16,6 +16,7 @@ import { useTranslation } from "next-i18next"; import { useUpdateCollection } from "@/hooks/store/collections"; import { useUser } from "@/hooks/store/user"; import CopyButton from "../CopyButton"; +import { useRouter } from "next/router"; type Props = { onClose: Function; @@ -94,16 +95,22 @@ export default function EditCollectionSharingModal({ setMemberIdentifier(""); }; + const router = useRouter(); + + const isPublicRoute = router.pathname.startsWith("/public") ? true : false; + return (

    - {permissions === true ? t("share_and_collaborate") : t("team")} + {permissions === true && !isPublicRoute + ? t("share_and_collaborate") + : t("team")}

    - {permissions === true && ( + {permissions === true && !isPublicRoute && (

    {t("make_collection_public")}

    @@ -140,9 +147,11 @@ export default function EditCollectionSharingModal({
    )} - {permissions === true &&
    } + {permissions === true && !isPublicRoute && ( +
    + )} - {permissions === true && ( + {permissions === true && !isPublicRoute && ( <>

    {t("members")}

    @@ -254,7 +263,7 @@ export default function EditCollectionSharingModal({
    - {permissions === true ? ( + {permissions === true && !isPublicRoute ? (
    )} - {permissions === true && ( + {permissions === true && !isPublicRoute && ( )} - {permissions === true && ( + {permissions === true && !isPublicRoute && ( +
    + + ); +} diff --git a/lib/api/controllers/users/userId/updateUserById.ts b/lib/api/controllers/users/userId/updateUserById.ts index 6dd09a87..8bc5e0f4 100644 --- a/lib/api/controllers/users/userId/updateUserById.ts +++ b/lib/api/controllers/users/userId/updateUserById.ts @@ -208,6 +208,8 @@ export default async function updateUserById( archiveAsWaybackMachine: data.archiveAsWaybackMachine, linksRouteTo: data.linksRouteTo, preventDuplicateLinks: data.preventDuplicateLinks, + referredBy: + !user?.referredBy && data.referredBy ? data.referredBy : undefined, password: isInvited || (data.newPassword && data.newPassword !== "") ? newHashedPassword diff --git a/lib/shared/schemaValidation.ts b/lib/shared/schemaValidation.ts index 30398c06..bc6d445d 100644 --- a/lib/shared/schemaValidation.ts +++ b/lib/shared/schemaValidation.ts @@ -81,6 +81,7 @@ export const UpdateUserSchema = () => { collectionOrder: z.array(z.number()).optional(), linksRouteTo: z.nativeEnum(LinksRouteTo).optional(), whitelistedUsers: z.array(z.string().max(50)).optional(), + referredBy: z.string().max(100).optional(), }); }; diff --git a/pages/dashboard.tsx b/pages/dashboard.tsx index d58ddc9e..8b8310bb 100644 --- a/pages/dashboard.tsx +++ b/pages/dashboard.tsx @@ -1,5 +1,5 @@ import MainLayout from "@/layouts/MainLayout"; -import { useEffect, useMemo, useState } from "react"; +import { BaseSyntheticEvent, useEffect, useMemo, useState } from "react"; import Link from "next/link"; import React from "react"; import { toast } from "react-hot-toast"; @@ -16,7 +16,8 @@ import { useTags } from "@/hooks/store/tags"; import { useDashboardData } from "@/hooks/store/dashboardData"; import Links from "@/components/LinkViews/Links"; import useLocalSettingsStore from "@/store/localSettings"; -import Divider from "@/components/ui/Divider"; +import { useUpdateUser, useUser } from "@/hooks/store/user"; +import SurveyModal from "@/components/ModalContent/SurveyModal"; export default function Dashboard() { const { t } = useTranslation(); @@ -26,6 +27,7 @@ export default function Dashboard() { ...dashboardData } = useDashboardData(); const { data: tags = [] } = useTags(); + const { data: account = [] } = useUser(); const [numberOfLinks, setNumberOfLinks] = useState(0); @@ -41,6 +43,19 @@ export default function Dashboard() { ); }, [collections]); + useEffect(() => { + if ( + process.env.NEXT_PUBLIC_STRIPE === "true" && + account.id && + account.referredBy === null && + // if user is using Linkwarden for more than 3 days + new Date().getTime() - new Date(account.createdAt).getTime() > + 3 * 24 * 60 * 60 * 1000 + ) { + setShowsSurveyModal(true); + } + }, [account]); + const numberOfLinksToShow = useMemo(() => { if (window.innerWidth > 1900) { return 10; @@ -101,6 +116,42 @@ export default function Dashboard() { (localStorage.getItem("viewMode") as ViewMode) || ViewMode.Card ); + const [showSurveyModal, setShowsSurveyModal] = useState(false); + + const { data: user } = useUser(); + const updateUser = useUpdateUser(); + + const [submitLoader, setSubmitLoader] = useState(false); + + const submitSurvey = async (referer: string, other?: string) => { + if (submitLoader) return; + + setSubmitLoader(true); + + const load = toast.loading(t("applying")); + + await updateUser.mutateAsync( + { + ...user, + referredBy: referer === "other" ? "Other: " + other : referer, + }, + { + onSettled: (data, error) => { + console.log(data, error); + setSubmitLoader(false); + toast.dismiss(load); + + if (error) { + toast.error(error.message); + } else { + toast.success(t("thanks_for_feedback")); + setShowsSurveyModal(false); + } + }, + } + ); + }; + return (
    @@ -343,6 +394,14 @@ export default function Dashboard() { )}
    + {showSurveyModal && ( + { + setShowsSurveyModal(false); + }} + /> + )} {newLinkModal && setNewLinkModal(false)} />} ); diff --git a/pages/settings/account.tsx b/pages/settings/account.tsx index 3a15b20b..851a7c70 100644 --- a/pages/settings/account.tsx +++ b/pages/settings/account.tsx @@ -101,12 +101,6 @@ export default function Account() { password: password ? password : undefined, }, { - onSuccess: (data) => { - if (data.response.email !== user.email) { - toast.success(t("email_change_request")); - setEmailChangeVerificationModal(false); - } - }, onSettled: (data, error) => { setSubmitLoader(false); toast.dismiss(load); diff --git a/pages/subscribe.tsx b/pages/subscribe.tsx index 4c490f00..bcd1db2f 100644 --- a/pages/subscribe.tsx +++ b/pages/subscribe.tsx @@ -21,7 +21,6 @@ export default function Subscribe() { const { data: user = {} } = useUser(); useEffect(() => { - console.log("user", user); if ( session.status === "authenticated" && user.id && diff --git a/prisma/migrations/20241107123356_add_field/migration.sql b/prisma/migrations/20241107123356_add_field/migration.sql new file mode 100644 index 00000000..bd75a6cb --- /dev/null +++ b/prisma/migrations/20241107123356_add_field/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "referredBy" TEXT; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 13418433..89738ef4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -55,6 +55,7 @@ model User { archiveAsPDF Boolean @default(true) archiveAsWaybackMachine Boolean @default(false) isPrivate Boolean @default(false) + referredBy String? createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt } diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 33f9cfa7..39303d47 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -417,5 +417,14 @@ "remove_user": "Remove User", "continue_to_dashboard": "Continue to Dashboard", "confirm_user_removal_desc": "They will need to have a subscription to access Linkwarden again.", - "click_out_to_apply": "Click outside to apply" + "click_out_to_apply": "Click outside to apply", + "submit": "Submit", + "thanks_for_feedback": "Thanks for your feedback!", + "quick_survey": "Quick Survey", + "how_did_you_discover_linkwarden": "How did you discover Linkwarden?", + "rather_not_say": "Rather not say", + "search_engine": "Search Engine (Google, Bing, etc.)", + "reddit": "Reddit", + "lemmy": "Lemmy", + "people_recommendation": "Recommendation (Friend, Family, etc.)" } \ No newline at end of file From a18938ba2a2456446e74beb6a625a90ad914af0c Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Thu, 7 Nov 2024 16:46:26 -0500 Subject: [PATCH 15/33] minor fix --- pages/dashboard.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/pages/dashboard.tsx b/pages/dashboard.tsx index 8b8310bb..3ad21bd8 100644 --- a/pages/dashboard.tsx +++ b/pages/dashboard.tsx @@ -46,6 +46,7 @@ export default function Dashboard() { useEffect(() => { if ( process.env.NEXT_PUBLIC_STRIPE === "true" && + account && account.id && account.referredBy === null && // if user is using Linkwarden for more than 3 days From 8d366ae7d8245c07d9e41fe516129a8278804f39 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Thu, 7 Nov 2024 16:54:51 -0500 Subject: [PATCH 16/33] minor fix --- components/InputSelect/styles.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/components/InputSelect/styles.ts b/components/InputSelect/styles.ts index 6018a512..f05f4a51 100644 --- a/components/InputSelect/styles.ts +++ b/components/InputSelect/styles.ts @@ -31,7 +31,6 @@ export const styles: StylesConfig = { height: "full", borderRadius: "0.375rem", lineHeight: "1.25rem", - zIndex: 10, // "@media screen and (min-width: 1024px)": { // fontSize: "0.875rem", // }, From b14e77bdf951b53755c3fa8433539151b342a590 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Fri, 8 Nov 2024 04:48:31 -0500 Subject: [PATCH 17/33] minor fix --- .../LinkViews/LinkComponents/LinkMasonry.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/LinkViews/LinkComponents/LinkMasonry.tsx b/components/LinkViews/LinkComponents/LinkMasonry.tsx index 2b501ea8..71d3a2fb 100644 --- a/components/LinkViews/LinkComponents/LinkMasonry.tsx +++ b/components/LinkViews/LinkComponents/LinkMasonry.tsx @@ -155,14 +155,14 @@ export default function LinkMasonry({ link, editMode, columns }: Props) { : undefined } > -
    +
    + !editMode && window.open(generateLinkHref(link, user), "_blank") + } + > {show.image && previewAvailable(link) && ( -
    - !editMode && window.open(generateLinkHref(link, user), "_blank") - } - > +
    {previewAvailable(link) ? ( Date: Fri, 8 Nov 2024 05:24:18 -0500 Subject: [PATCH 18/33] minor fix --- components/IconGrid.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/components/IconGrid.tsx b/components/IconGrid.tsx index 494337e3..9a2f8830 100644 --- a/components/IconGrid.tsx +++ b/components/IconGrid.tsx @@ -18,7 +18,6 @@ type Props = { }; const IconGrid = ({ query, color, weight, iconName, setIconName }: Props) => { - // Memoize the filtered results to avoid recalculations on each render const filteredIcons = useMemo(() => { if (!query) { return icons; @@ -26,12 +25,10 @@ const IconGrid = ({ query, color, weight, iconName, setIconName }: Props) => { return fuse.search(query).map((result) => result.item); }, [query]); - // Grid configuration const columnCount = 6; const rowCount = Math.ceil(filteredIcons.length / columnCount); const GUTTER_SIZE = 5; - // Render a single cell (icon) in the grid const Cell = ({ columnIndex, rowIndex, style }: any) => { const index = rowIndex * columnCount + columnIndex; if (index >= filteredIcons.length) return null; // Prevent overflow @@ -60,7 +57,7 @@ const IconGrid = ({ query, color, weight, iconName, setIconName }: Props) => { ); }; - const innerElementType = forwardRef(({ style, ...rest }: any, ref) => ( + const InnerElementType = forwardRef(({ style, ...rest }: any, ref) => (
    { /> )); + InnerElementType.displayName = "InnerElementType"; + return ( Date: Fri, 8 Nov 2024 12:25:31 -0500 Subject: [PATCH 19/33] minor fix --- pages/settings/billing.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/settings/billing.tsx b/pages/settings/billing.tsx index 37a938f2..cf5db1ff 100644 --- a/pages/settings/billing.tsx +++ b/pages/settings/billing.tsx @@ -191,7 +191,7 @@ export default function Billing() {

    {user.id !== account.id && ( - +
    From 8593df4673f49982ab2e0653033f4fbe073ec760 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Fri, 8 Nov 2024 17:21:20 -0500 Subject: [PATCH 20/33] bug fixed --- .../controllers/users/userId/deleteUserById.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/api/controllers/users/userId/deleteUserById.ts b/lib/api/controllers/users/userId/deleteUserById.ts index 2570b25e..da2f10e0 100644 --- a/lib/api/controllers/users/userId/deleteUserById.ts +++ b/lib/api/controllers/users/userId/deleteUserById.ts @@ -58,8 +58,6 @@ export default async function deleteUserById( } } else { if (user.parentSubscriptionId) { - console.log(userId, user.parentSubscriptionId); - return { response: "Permission denied.", status: 401, @@ -89,18 +87,16 @@ export default async function deleteUserById( disconnect: true, }, }, - select: { - id: true, - }, }); - await updateSeats( - user.subscriptions.stripeSubscriptionId, - user.subscriptions.quantity - 1 - ); + if (removeUser.emailVerified) + await updateSeats( + user.subscriptions.stripeSubscriptionId, + user.subscriptions.quantity - 1 + ); return { - response: removeUser, + response: "Account removed from subscription.", status: 200, }; } @@ -209,7 +205,7 @@ export default async function deleteUserById( status: 200, }; } - } else if (user.parentSubscription?.id) { + } else if (user.parentSubscription?.id && user && user.emailVerified) { await updateSeats( user.parentSubscription.stripeSubscriptionId, user.parentSubscription.quantity - 1 From 7ca574b76f820ca47f044bf3758c5e3b3df033cb Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Fri, 8 Nov 2024 17:57:50 -0500 Subject: [PATCH 21/33] bug fixes --- components/InputSelect/styles.ts | 4 + hooks/store/publicTags.tsx | 1 - lib/api/controllers/tags/getTags.ts | 74 +++++++++++-------- lib/shared/schemaValidation.ts | 2 +- pages/api/v1/public/collections/tags/index.ts | 2 +- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/components/InputSelect/styles.ts b/components/InputSelect/styles.ts index f05f4a51..369366ce 100644 --- a/components/InputSelect/styles.ts +++ b/components/InputSelect/styles.ts @@ -16,6 +16,10 @@ export const styles: StylesConfig = { }, transition: "all 100ms", }), + menu: (styles) => ({ + ...styles, + zIndex: 10, + }), control: (styles, state) => ({ ...styles, fontFamily: font, diff --git a/hooks/store/publicTags.tsx b/hooks/store/publicTags.tsx index aedeb75f..cf89491e 100644 --- a/hooks/store/publicTags.tsx +++ b/hooks/store/publicTags.tsx @@ -23,7 +23,6 @@ const usePublicTags = (): UseQueryResult => { const data = await response.json(); return data.response; }, - enabled: status === "authenticated", }); }; diff --git a/lib/api/controllers/tags/getTags.ts b/lib/api/controllers/tags/getTags.ts index 90c9f30e..21d1df36 100644 --- a/lib/api/controllers/tags/getTags.ts +++ b/lib/api/controllers/tags/getTags.ts @@ -7,8 +7,9 @@ export default async function getTags({ userId?: number; collectionId?: number; }) { - // Remove empty tags - if (userId) + console.log("collectionId", collectionId); + if (userId) { + // Remove empty tags await prisma.tag.deleteMany({ where: { ownerId: userId, @@ -18,43 +19,56 @@ export default async function getTags({ }, }); - const tags = await prisma.tag.findMany({ - where: { - OR: [ - { ownerId: userId }, // Tags owned by the user - { - links: { - some: { - collection: { - members: { - some: { - userId, // Tags from collections where the user is a member + const tags = await prisma.tag.findMany({ + where: { + OR: [ + { ownerId: userId }, // Tags owned by the user + { + links: { + some: { + collection: { + members: { + some: { + userId, // Tags from collections where the user is a member + }, }, }, }, }, }, + ], + }, + include: { + _count: { + select: { links: true }, }, - { - links: { - some: { - collectionId, + }, + // orderBy: { + // links: { + // _count: "desc", + // }, + // }, + }); + + return { response: tags, status: 200 }; + } else if (collectionId) { + const tags = await prisma.tag.findMany({ + where: { + links: { + some: { + collection: { + id: collectionId, }, }, }, - ], - }, - include: { - _count: { - select: { links: true }, }, - }, - // orderBy: { - // links: { - // _count: "desc", - // }, - // }, - }); + include: { + _count: { + select: { links: true }, + }, + }, + }); - return { response: tags, status: 200 }; + return { response: tags, status: 200 }; + } } diff --git a/lib/shared/schemaValidation.ts b/lib/shared/schemaValidation.ts index bc6d445d..de3c8299 100644 --- a/lib/shared/schemaValidation.ts +++ b/lib/shared/schemaValidation.ts @@ -81,7 +81,7 @@ export const UpdateUserSchema = () => { collectionOrder: z.array(z.number()).optional(), linksRouteTo: z.nativeEnum(LinksRouteTo).optional(), whitelistedUsers: z.array(z.string().max(50)).optional(), - referredBy: z.string().max(100).optional(), + referredBy: z.string().max(100).nullish(), }); }; diff --git a/pages/api/v1/public/collections/tags/index.ts b/pages/api/v1/public/collections/tags/index.ts index 43e693c1..9b8217d4 100644 --- a/pages/api/v1/public/collections/tags/index.ts +++ b/pages/api/v1/public/collections/tags/index.ts @@ -37,6 +37,6 @@ export default async function collections( collectionId: collection.id, }); - return res.status(tags.status).json({ response: tags.response }); + return res.status(tags?.status || 500).json({ response: tags?.response }); } } From c85c3bb0d71a3d939e8503dac182f9766aeff407 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Fri, 8 Nov 2024 18:03:00 -0500 Subject: [PATCH 22/33] minor fix --- lib/api/controllers/tags/getTags.ts | 5 ----- pages/public/collections/[id].tsx | 11 ++--------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/lib/api/controllers/tags/getTags.ts b/lib/api/controllers/tags/getTags.ts index 21d1df36..61ef0913 100644 --- a/lib/api/controllers/tags/getTags.ts +++ b/lib/api/controllers/tags/getTags.ts @@ -62,11 +62,6 @@ export default async function getTags({ }, }, }, - include: { - _count: { - select: { links: true }, - }, - }, }); return { response: tags, status: 200 }; diff --git a/pages/public/collections/[id].tsx b/pages/public/collections/[id].tsx index 95adcd66..e07ec8dd 100644 --- a/pages/public/collections/[id].tsx +++ b/pages/public/collections/[id].tsx @@ -252,11 +252,7 @@ export default function PublicCollections() { : "bg-neutral-content/20 hover:bg-neutral/20" } duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 rounded-md h-8`} > - -

    {t("all_links")}

    -
    - {collection._count?.links} -
    +

    {t("all_links")}

    {tags @@ -279,10 +275,7 @@ export default function PublicCollections() { } duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 rounded-md h-8`} > -

    {e}

    -
    - {tags.filter((t) => t.name === e)[0]._count.links} -
    +

    {e}

    ); From 9b58ea5c98d185e59e72eae12e60036449b40168 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sat, 9 Nov 2024 13:45:11 -0500 Subject: [PATCH 23/33] minor change --- lib/api/controllers/tags/getTags.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/api/controllers/tags/getTags.ts b/lib/api/controllers/tags/getTags.ts index 61ef0913..efc30bbf 100644 --- a/lib/api/controllers/tags/getTags.ts +++ b/lib/api/controllers/tags/getTags.ts @@ -7,7 +7,6 @@ export default async function getTags({ userId?: number; collectionId?: number; }) { - console.log("collectionId", collectionId); if (userId) { // Remove empty tags await prisma.tag.deleteMany({ From 0b7acb35b7f4c727d7fe8e2c6d2181f843d0d703 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sat, 9 Nov 2024 14:14:13 -0500 Subject: [PATCH 24/33] minor change --- components/ProfileDropdown.tsx | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/components/ProfileDropdown.tsx b/components/ProfileDropdown.tsx index 9d1260b8..80d51192 100644 --- a/components/ProfileDropdown.tsx +++ b/components/ProfileDropdown.tsx @@ -6,8 +6,6 @@ import { signOut } from "next-auth/react"; import { useTranslation } from "next-i18next"; import { useUser } from "@/hooks/store/user"; -const stripeEnabled = process.env.NEXT_PUBLIC_STRIPE === "true"; - export default function ProfileDropdown() { const { t } = useTranslation(); const { settings, updateSettings } = useLocalSettingsStore(); @@ -75,19 +73,6 @@ export default function ProfileDropdown() { )} - {!user.parentSubscriptionId && stripeEnabled && ( -
  • - (document?.activeElement as HTMLElement)?.blur()} - tabIndex={0} - role="button" - className="whitespace-nowrap" - > - {t("invite_users")} - -
  • - )}
  • { From 213105942b4e5d55f6f0406972dc5e4c725f8ac8 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sat, 9 Nov 2024 15:02:59 -0500 Subject: [PATCH 25/33] minor change --- components/ModalContent/InviteModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ModalContent/InviteModal.tsx b/components/ModalContent/InviteModal.tsx index 6d83e83e..c2679032 100644 --- a/components/ModalContent/InviteModal.tsx +++ b/components/ModalContent/InviteModal.tsx @@ -102,7 +102,7 @@ export default function InviteModal({ onClose }: Props) {

    {t("invite_user_note")}

    From 9c9fd969bc53242acf73165436f1234676872ae3 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sat, 9 Nov 2024 15:27:15 -0500 Subject: [PATCH 26/33] minor fix --- pages/settings/billing.tsx | 7 ++++++- public/locales/en/common.json | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pages/settings/billing.tsx b/pages/settings/billing.tsx index cf5db1ff..d1bd80b9 100644 --- a/pages/settings/billing.tsx +++ b/pages/settings/billing.tsx @@ -255,7 +255,12 @@ export default function Billing() {

    - {t("seats_purchased", { count: account?.subscription?.quantity })} + {t( + account?.subscription?.quantity === 1 + ? "seat_purchased" + : "seats_purchased", + { count: account?.subscription?.quantity } + )}

    {inviteModal && setInviteModal(false)} />} {deleteUserModal.isOpen && deleteUserModal.userId && ( diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 39303d47..4bafb1bc 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -411,6 +411,7 @@ "active": "Active", "manage_seats": "Manage Seats", "seats_purchased": "{{count}} seats purchased", + "seat_purchased": "{{count}} seat purchased", "date_added": "Date Added", "resend_invite": "Resend Invitation", "resend_invite_success": "Invitation Resent!", From 836360f99d55f75026afe9f5f1d0a67b7e8a0745 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sat, 9 Nov 2024 23:07:01 -0500 Subject: [PATCH 27/33] bug fixed --- components/CollectionListing.tsx | 17 ++++------- pages/dashboard.tsx | 49 +++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/components/CollectionListing.tsx b/components/CollectionListing.tsx index 3ff24151..f218b462 100644 --- a/components/CollectionListing.tsx +++ b/components/CollectionListing.tsx @@ -29,7 +29,7 @@ const CollectionListing = () => { const updateCollection = useUpdateCollection(); const { data: collections = [], isLoading } = useCollections(); - const { data: user = {} } = useUser(); + const { data: user = {}, refetch } = useUser(); const updateUser = useUpdateUser(); const router = useRouter(); @@ -38,10 +38,7 @@ const CollectionListing = () => { const [tree, setTree] = useState(); const initialTree = useMemo(() => { - if ( - // !tree && - collections.length > 0 - ) { + if (collections.length > 0) { return buildTreeFromCollections( collections, router, @@ -52,12 +49,12 @@ const CollectionListing = () => { }, [collections, user, router]); useEffect(() => { - // if (!tree) setTree(initialTree); }, [initialTree]); useEffect(() => { if (user.username) { + refetch(); if ( (!user.collectionOrder || user.collectionOrder.length === 0) && collections.length > 0 @@ -65,11 +62,7 @@ const CollectionListing = () => { updateUser.mutate({ ...user, collectionOrder: collections - .filter( - (e) => - e.parentId === null || - !collections.find((i) => i.id === e.parentId) - ) // Filter out collections with non-null parentId + .filter((e) => e.parentId === null) .map((e) => e.id as number), }); else { @@ -103,7 +96,7 @@ const CollectionListing = () => { } } } - }, [collections]); + }, [user, collections]); const onExpand = (movedCollectionId: ItemId) => { setTree((currentTree) => diff --git a/pages/dashboard.tsx b/pages/dashboard.tsx index 3ad21bd8..dc26e569 100644 --- a/pages/dashboard.tsx +++ b/pages/dashboard.tsx @@ -1,5 +1,5 @@ import MainLayout from "@/layouts/MainLayout"; -import { BaseSyntheticEvent, useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import Link from "next/link"; import React from "react"; import { toast } from "react-hot-toast"; @@ -90,23 +90,44 @@ export default function Dashboard() { data: request, }; - const response = await fetch("/api/v1/migration", { - method: "POST", - body: JSON.stringify(body), - }); + try { + const response = await fetch("/api/v1/migration", { + method: "POST", + body: JSON.stringify(body), + }); - await response.json(); + if (!response.ok) { + const errorData = await response.json(); + toast.dismiss(load); - toast.dismiss(load); + toast.error( + errorData.response || + "Failed to import bookmarks. Please try again." + ); + return; + } - toast.success("Imported the Bookmarks! Reloading the page..."); + await response.json(); + toast.dismiss(load); + toast.success("Imported the Bookmarks! Reloading the page..."); - setTimeout(() => { - location.reload(); - }, 2000); + setTimeout(() => { + location.reload(); + }, 2000); + } catch (error) { + console.error("Request failed", error); + toast.dismiss(load); + toast.error( + "An error occurred while importing bookmarks. Please check the logs for more info." + ); + } }; + reader.onerror = function (e) { - console.log("Error:", e); + console.log("Error reading file:", e); + toast.error( + "Failed to read the file. Please make sure the file is correct and try again." + ); }; } }; @@ -233,7 +254,7 @@ export default function Dashboard() { />
  • ) : ( -
    +

    {t("view_added_links_here")}

    @@ -382,7 +403,7 @@ export default function Dashboard() { ) : (

    From e39645e135d91a4667884d563cc4e31c6ebdaefb Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sat, 9 Nov 2024 23:11:03 -0500 Subject: [PATCH 28/33] bug fix --- pages/settings/account.tsx | 61 +++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/pages/settings/account.tsx b/pages/settings/account.tsx index 851a7c70..d4f99fe8 100644 --- a/pages/settings/account.tsx +++ b/pages/settings/account.tsx @@ -127,39 +127,64 @@ export default function Account() { }; const importBookmarks = async ( - e: ChangeEvent, + e: React.ChangeEvent, format: MigrationFormat ) => { - setSubmitLoader(true); - const file = e.target.files?.[0]; + const file: File | null = e.target.files && e.target.files[0]; if (file) { - var reader = new FileReader(); + const reader = new FileReader(); reader.readAsText(file, "UTF-8"); reader.onload = async function (e) { - const load = toast.loading(t("importing_bookmarks")); + const load = toast.loading("Importing..."); + const request: string = e.target?.result as string; - const body: MigrationRequest = { format, data: request }; - const response = await fetch("/api/v1/migration", { - method: "POST", - body: JSON.stringify(body), - }); - const data = await response.json(); - toast.dismiss(load); - if (response.ok) { - toast.success(t("import_success")); + + const body: MigrationRequest = { + format, + data: request, + }; + + try { + const response = await fetch("/api/v1/migration", { + method: "POST", + body: JSON.stringify(body), + }); + + if (!response.ok) { + const errorData = await response.json(); + toast.dismiss(load); + + toast.error( + errorData.response || + "Failed to import bookmarks. Please try again." + ); + return; + } + + await response.json(); + toast.dismiss(load); + toast.success("Imported the Bookmarks! Reloading the page..."); + setTimeout(() => { location.reload(); }, 2000); - } else { - toast.error(data.response as string); + } catch (error) { + console.error("Request failed", error); + toast.dismiss(load); + toast.error( + "An error occurred while importing bookmarks. Please check the logs for more info." + ); } }; + reader.onerror = function (e) { - console.log("Error:", e); + console.log("Error reading file:", e); + toast.error( + "Failed to read the file. Please make sure the file is correct and try again." + ); }; } - setSubmitLoader(false); }; const [whitelistedUsersTextbox, setWhiteListedUsersTextbox] = useState(""); From 78ecf3ddb5e6ef9f043f8a6d13e88152aa04ad1e Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sat, 9 Nov 2024 23:33:13 -0500 Subject: [PATCH 29/33] bug fix --- components/Drawer.tsx | 4 ++-- components/LinkDetails.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/Drawer.tsx b/components/Drawer.tsx index 59af893b..7400e44f 100644 --- a/components/Drawer.tsx +++ b/components/Drawer.tsx @@ -38,7 +38,7 @@ export default function Drawer({ > - +

    - +
    - {link.name || t("untitled")} + {unescapeString(link.name) || t("untitled")}

    )} From 6842da42831d2cee71c076d7ed85159aefb5b838 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sat, 9 Nov 2024 23:59:12 -0500 Subject: [PATCH 30/33] new feature: open all links --- pages/collections/[id].tsx | 15 +++++++++++++++ public/locales/en/common.json | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pages/collections/[id].tsx b/pages/collections/[id].tsx index 7abd042f..07804df3 100644 --- a/pages/collections/[id].tsx +++ b/pages/collections/[id].tsx @@ -143,6 +143,21 @@ export default function Index() {
      +
    • +
      { + (document?.activeElement as HTMLElement)?.blur(); + for (const link of links) { + if (link.url) window.open(link.url, "_blank"); + } + }} + className="whitespace-nowrap" + > + {t("open_all_links")} +
      +
    • {permissions === true && (
    • Date: Sun, 10 Nov 2024 00:27:13 -0500 Subject: [PATCH 31/33] minor change --- components/ModalContent/SurveyModal.tsx | 1 - pages/dashboard.tsx | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/components/ModalContent/SurveyModal.tsx b/components/ModalContent/SurveyModal.tsx index 5b6a2ba2..354c1dc3 100644 --- a/components/ModalContent/SurveyModal.tsx +++ b/components/ModalContent/SurveyModal.tsx @@ -59,7 +59,6 @@ export default function SurveyModal({ onClose, submit }: Props) { intent="accent" onClick={() => submit(referer, other)} > - {t("submit")}
      diff --git a/pages/dashboard.tsx b/pages/dashboard.tsx index dc26e569..cc67e66d 100644 --- a/pages/dashboard.tsx +++ b/pages/dashboard.tsx @@ -53,7 +53,9 @@ export default function Dashboard() { new Date().getTime() - new Date(account.createdAt).getTime() > 3 * 24 * 60 * 60 * 1000 ) { - setShowsSurveyModal(true); + setTimeout(() => { + setShowsSurveyModal(true); + }, 1000); } }, [account]); From 46f81ebf254c1829435adeacf5bffb78f6891c89 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Sun, 10 Nov 2024 16:42:04 -0500 Subject: [PATCH 32/33] add info to inviteModal --- components/ModalContent/InviteModal.tsx | 8 +++++++- public/locales/en/common.json | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/components/ModalContent/InviteModal.tsx b/components/ModalContent/InviteModal.tsx index c2679032..eb488db8 100644 --- a/components/ModalContent/InviteModal.tsx +++ b/components/ModalContent/InviteModal.tsx @@ -100,7 +100,13 @@ export default function InviteModal({ onClose }: Props) {
      -

      {t("invite_user_note")}

      +

      {t("invite_user_note")}

      +

      + {t("invite_user_price", { + price: 4, + priceAnnual: 36, + })} +

      Date: Tue, 12 Nov 2024 08:36:40 -0500 Subject: [PATCH 33/33] small fix --- pages/api/v1/tags/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/v1/tags/index.ts b/pages/api/v1/tags/index.ts index 3135001c..58add22c 100644 --- a/pages/api/v1/tags/index.ts +++ b/pages/api/v1/tags/index.ts @@ -10,6 +10,6 @@ export default async function tags(req: NextApiRequest, res: NextApiResponse) { const tags = await getTags({ userId: user.id, }); - return res.status(tags.status).json({ response: tags.response }); + return res.status(tags?.status || 500).json({ response: tags?.response }); } }