mirror of
https://github.com/walkxcode/dashboard-icons.git
synced 2025-11-26 22:58:41 +01:00
disable static generation for community/[icon]
This commit is contained in:
@@ -1,10 +1,17 @@
|
||||
import type { NextConfig } from "next"
|
||||
import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
images: {
|
||||
unoptimized: true,
|
||||
},
|
||||
cacheComponents: false,
|
||||
images: {
|
||||
remotePatterns: [
|
||||
new URL(
|
||||
"https://pb.dashboardicons.com/**",
|
||||
),
|
||||
new URL(
|
||||
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/**",
|
||||
),
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig
|
||||
export default nextConfig
|
||||
@@ -17,6 +17,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "^5.2.1",
|
||||
"@posthog/nextjs-config": "^1.4.0",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.15",
|
||||
"@radix-ui/react-aspect-ratio": "^1.1.7",
|
||||
@@ -95,6 +96,7 @@
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@biomejs/biome",
|
||||
"@posthog/cli",
|
||||
"@tailwindcss/oxide",
|
||||
"core-js",
|
||||
"esbuild",
|
||||
|
||||
482
web/pnpm-lock.yaml
generated
482
web/pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ importers:
|
||||
'@hookform/resolvers':
|
||||
specifier: ^5.2.1
|
||||
version: 5.2.1(react-hook-form@7.66.0(react@19.2.0))
|
||||
'@posthog/nextjs-config':
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.0(next@16.0.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))
|
||||
'@radix-ui/react-accordion':
|
||||
specifier: ^1.2.12
|
||||
version: 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.5))(@types/react@19.2.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
@@ -750,6 +753,18 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@isaacs/balanced-match@4.0.1':
|
||||
resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
'@isaacs/brace-expansion@5.0.0':
|
||||
resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.12':
|
||||
resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==}
|
||||
|
||||
@@ -829,9 +844,20 @@ packages:
|
||||
'@poppinss/exception@1.2.2':
|
||||
resolution: {integrity: sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==}
|
||||
|
||||
'@posthog/cli@0.5.12':
|
||||
resolution: {integrity: sha512-woMmA4ChCzpJUa939SKfc11bYDNSkqHvhcvPn+EarV1ivIkmBu9gBOAZW1S/MfH76LCJE7tesuR0EOxo0zYjvw==}
|
||||
engines: {node: '>=14', npm: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
'@posthog/core@1.5.2':
|
||||
resolution: {integrity: sha512-iedUP3EnOPPxTA2VaIrsrd29lSZnUV+ZrMnvY56timRVeZAXoYCkmjfIs3KBAsF8OUT5h1GXLSkoQdrV0r31OQ==}
|
||||
|
||||
'@posthog/nextjs-config@1.4.0':
|
||||
resolution: {integrity: sha512-Ar2M6IXv+5QZ8uaeVHHxJyghvapRSnHzZHpz5TKAhysASikMMwg2L9hGmeNhCxgzgljyopyyda96DdL0j742xA==}
|
||||
engines: {node: '>=20'}
|
||||
peerDependencies:
|
||||
next: '>12.1.0'
|
||||
|
||||
'@radix-ui/number@1.1.1':
|
||||
resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==}
|
||||
|
||||
@@ -1778,17 +1804,46 @@ packages:
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
ansi-regex@5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-regex@6.2.2:
|
||||
resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-styles@6.2.3:
|
||||
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
aria-hidden@1.2.6:
|
||||
resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
attr-accept@2.2.5:
|
||||
resolution: {integrity: sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
axios-proxy-builder@0.1.2:
|
||||
resolution: {integrity: sha512-6uBVsBZzkB3tCC8iyx59mCjQckhB8+GQrI9Cop8eC7ybIsvs/KtnNgEBfRMSEa7GqK2VBGUzgjNYMdPIfotyPA==}
|
||||
|
||||
axios@1.13.2:
|
||||
resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==}
|
||||
|
||||
blake3-wasm@2.1.5:
|
||||
resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
caniuse-lite@1.0.30001726:
|
||||
resolution: {integrity: sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==}
|
||||
|
||||
@@ -1801,6 +1856,10 @@ packages:
|
||||
client-only@0.0.1:
|
||||
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
|
||||
|
||||
clone@1.0.4:
|
||||
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
clsx@2.1.1:
|
||||
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -1825,6 +1884,14 @@ packages:
|
||||
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
||||
engines: {node: '>=12.5.0'}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
console.table@0.10.0:
|
||||
resolution: {integrity: sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==}
|
||||
engines: {node: '> 0.10'}
|
||||
|
||||
cookie@1.0.2:
|
||||
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -1895,6 +1962,13 @@ packages:
|
||||
decimal.js-light@2.5.1:
|
||||
resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==}
|
||||
|
||||
defaults@1.0.4:
|
||||
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
|
||||
|
||||
delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1902,6 +1976,16 @@ packages:
|
||||
detect-node-es@1.1.0:
|
||||
resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
easy-table@1.1.0:
|
||||
resolution: {integrity: sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==}
|
||||
|
||||
embla-carousel-react@8.6.0:
|
||||
resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==}
|
||||
peerDependencies:
|
||||
@@ -1915,6 +1999,12 @@ packages:
|
||||
embla-carousel@8.6.0:
|
||||
resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
|
||||
emoji-regex@9.2.2:
|
||||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
||||
|
||||
enhanced-resolve@5.18.3:
|
||||
resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
@@ -1922,6 +2012,22 @@ packages:
|
||||
error-stack-parser-es@1.0.5:
|
||||
resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
|
||||
|
||||
es-define-property@1.0.1:
|
||||
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-errors@1.3.0:
|
||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-toolkit@1.42.0:
|
||||
resolution: {integrity: sha512-SLHIyY7VfDJBM8clz4+T2oquwTQxEzu263AyhVK4jREOAwJ+8eebaa4wM3nlvnAqhDrMm2EsA6hWHaQsMPQ1nA==}
|
||||
|
||||
@@ -1944,6 +2050,23 @@ packages:
|
||||
resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
follow-redirects@1.15.11:
|
||||
resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
|
||||
foreground-child@3.3.1:
|
||||
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
form-data@4.0.5:
|
||||
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
framer-motion@12.23.24:
|
||||
resolution: {integrity: sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w==}
|
||||
peerDependencies:
|
||||
@@ -1963,16 +2086,48 @@ packages:
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
get-nonce@1.0.1:
|
||||
resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
get-proto@1.0.1:
|
||||
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
glob-to-regexp@0.4.1:
|
||||
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
|
||||
|
||||
glob@11.1.0:
|
||||
resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==}
|
||||
engines: {node: 20 || >=22}
|
||||
hasBin: true
|
||||
|
||||
gopd@1.2.0:
|
||||
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
||||
has-symbols@1.1.0:
|
||||
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
hasown@2.0.2:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
immer@10.2.0:
|
||||
resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==}
|
||||
|
||||
@@ -1989,9 +2144,17 @@ packages:
|
||||
is-arrayish@0.3.2:
|
||||
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
|
||||
|
||||
is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
jackspeak@4.1.1:
|
||||
resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
jiti@2.6.1:
|
||||
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
||||
hasBin: true
|
||||
@@ -2077,6 +2240,10 @@ packages:
|
||||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||
hasBin: true
|
||||
|
||||
lru-cache@11.2.2:
|
||||
resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
lucide-react@0.553.0:
|
||||
resolution: {integrity: sha512-BRgX5zrWmNy/lkVAe0dXBgd7XQdZ3HTf+Hwe3c9WK6dqgnj9h+hxV+MDncM88xDWlCq27+TKvHGE70ViODNILw==}
|
||||
peerDependencies:
|
||||
@@ -2085,6 +2252,18 @@ packages:
|
||||
magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
|
||||
math-intrinsics@1.1.0:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime@3.0.0:
|
||||
resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
@@ -2095,6 +2274,14 @@ packages:
|
||||
engines: {node: '>=18.0.0'}
|
||||
hasBin: true
|
||||
|
||||
minimatch@10.1.1:
|
||||
resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
minipass@7.1.2:
|
||||
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
motion-dom@12.23.23:
|
||||
resolution: {integrity: sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==}
|
||||
|
||||
@@ -2151,10 +2338,17 @@ packages:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
package-json-from-dist@1.0.1:
|
||||
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
|
||||
|
||||
path-key@3.1.1:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
path-scurry@2.0.1:
|
||||
resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
path-to-regexp@6.3.0:
|
||||
resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
|
||||
|
||||
@@ -2188,6 +2382,9 @@ packages:
|
||||
prop-types@15.8.1:
|
||||
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
||||
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
radix-ui@1.4.3:
|
||||
resolution: {integrity: sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==}
|
||||
peerDependencies:
|
||||
@@ -2301,6 +2498,11 @@ packages:
|
||||
reselect@5.1.1:
|
||||
resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
|
||||
|
||||
rimraf@6.1.0:
|
||||
resolution: {integrity: sha512-DxdlA1bdNzkZK7JiNWH+BAx1x4tEJWoTofIopFo6qWUU94jYrFZ0ubY05TqH3nWPJ1nKa1JWVFDINZ3fnrle/A==}
|
||||
engines: {node: 20 || >=22}
|
||||
hasBin: true
|
||||
|
||||
scheduler@0.27.0:
|
||||
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
|
||||
|
||||
@@ -2325,6 +2527,10 @@ packages:
|
||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
signal-exit@4.1.0:
|
||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
simple-swizzle@0.2.2:
|
||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
||||
|
||||
@@ -2342,6 +2548,22 @@ packages:
|
||||
resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==}
|
||||
engines: {node: '>=4', npm: '>=6'}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
string-width@5.1.2:
|
||||
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-ansi@7.1.2:
|
||||
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
styled-jsx@5.1.6:
|
||||
resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
@@ -2380,6 +2602,10 @@ packages:
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
tunnel@0.0.6:
|
||||
resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==}
|
||||
engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'}
|
||||
|
||||
tw-animate-css@1.4.0:
|
||||
resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==}
|
||||
|
||||
@@ -2432,6 +2658,9 @@ packages:
|
||||
victory-vendor@37.3.6:
|
||||
resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==}
|
||||
|
||||
wcwidth@1.0.1:
|
||||
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
||||
|
||||
web-vitals@4.2.4:
|
||||
resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==}
|
||||
|
||||
@@ -2455,6 +2684,14 @@ packages:
|
||||
'@cloudflare/workers-types':
|
||||
optional: true
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
wrap-ansi@8.1.0:
|
||||
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
ws@8.18.0:
|
||||
resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
@@ -2823,6 +3060,21 @@ snapshots:
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@isaacs/balanced-match@4.0.1': {}
|
||||
|
||||
'@isaacs/brace-expansion@5.0.0':
|
||||
dependencies:
|
||||
'@isaacs/balanced-match': 4.0.1
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
dependencies:
|
||||
string-width: 5.1.2
|
||||
string-width-cjs: string-width@4.2.3
|
||||
strip-ansi: 7.1.2
|
||||
strip-ansi-cjs: strip-ansi@6.0.1
|
||||
wrap-ansi: 8.1.0
|
||||
wrap-ansi-cjs: wrap-ansi@7.0.0
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.12':
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
@@ -2885,10 +3137,29 @@ snapshots:
|
||||
|
||||
'@poppinss/exception@1.2.2': {}
|
||||
|
||||
'@posthog/cli@0.5.12':
|
||||
dependencies:
|
||||
axios: 1.13.2
|
||||
axios-proxy-builder: 0.1.2
|
||||
console.table: 0.10.0
|
||||
detect-libc: 2.1.2
|
||||
rimraf: 6.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
'@posthog/core@1.5.2':
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
|
||||
'@posthog/nextjs-config@1.4.0(next@16.0.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))':
|
||||
dependencies:
|
||||
'@posthog/cli': 0.5.12
|
||||
'@posthog/core': 1.5.2
|
||||
next: 16.0.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
semver: 7.7.3
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
'@radix-ui/number@1.1.1': {}
|
||||
|
||||
'@radix-ui/primitive@1.1.3': {}
|
||||
@@ -3850,14 +4121,43 @@ snapshots:
|
||||
|
||||
acorn@8.14.0: {}
|
||||
|
||||
ansi-regex@5.0.1: {}
|
||||
|
||||
ansi-regex@6.2.2: {}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
|
||||
ansi-styles@6.2.3: {}
|
||||
|
||||
aria-hidden@1.2.6:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
attr-accept@2.2.5: {}
|
||||
|
||||
axios-proxy-builder@0.1.2:
|
||||
dependencies:
|
||||
tunnel: 0.0.6
|
||||
|
||||
axios@1.13.2:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.11
|
||||
form-data: 4.0.5
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
blake3-wasm@2.1.5: {}
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
|
||||
caniuse-lite@1.0.30001726: {}
|
||||
|
||||
canvas-confetti@1.9.3: {}
|
||||
@@ -3868,6 +4168,9 @@ snapshots:
|
||||
|
||||
client-only@0.0.1: {}
|
||||
|
||||
clone@1.0.4:
|
||||
optional: true
|
||||
|
||||
clsx@2.1.1: {}
|
||||
|
||||
cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.5))(@types/react@19.2.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
||||
@@ -3898,6 +4201,14 @@ snapshots:
|
||||
color-convert: 2.0.1
|
||||
color-string: 1.9.1
|
||||
|
||||
combined-stream@1.0.8:
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
|
||||
console.table@0.10.0:
|
||||
dependencies:
|
||||
easy-table: 1.1.0
|
||||
|
||||
cookie@1.0.2: {}
|
||||
|
||||
core-js@3.41.0: {}
|
||||
@@ -3956,10 +4267,29 @@ snapshots:
|
||||
|
||||
decimal.js-light@2.5.1: {}
|
||||
|
||||
defaults@1.0.4:
|
||||
dependencies:
|
||||
clone: 1.0.4
|
||||
optional: true
|
||||
|
||||
delayed-stream@1.0.0: {}
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
detect-node-es@1.1.0: {}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
easy-table@1.1.0:
|
||||
optionalDependencies:
|
||||
wcwidth: 1.0.1
|
||||
|
||||
embla-carousel-react@8.6.0(react@19.2.0):
|
||||
dependencies:
|
||||
embla-carousel: 8.6.0
|
||||
@@ -3972,6 +4302,10 @@ snapshots:
|
||||
|
||||
embla-carousel@8.6.0: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
emoji-regex@9.2.2: {}
|
||||
|
||||
enhanced-resolve@5.18.3:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
@@ -3979,6 +4313,21 @@ snapshots:
|
||||
|
||||
error-stack-parser-es@1.0.5: {}
|
||||
|
||||
es-define-property@1.0.1: {}
|
||||
|
||||
es-errors@1.3.0: {}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
has-tostringtag: 1.0.2
|
||||
hasown: 2.0.2
|
||||
|
||||
es-toolkit@1.42.0: {}
|
||||
|
||||
esbuild@0.25.4:
|
||||
@@ -4019,6 +4368,21 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
follow-redirects@1.15.11: {}
|
||||
|
||||
foreground-child@3.3.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
signal-exit: 4.1.0
|
||||
|
||||
form-data@4.0.5:
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
es-set-tostringtag: 2.1.0
|
||||
hasown: 2.0.2
|
||||
mime-types: 2.1.35
|
||||
|
||||
framer-motion@12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
||||
dependencies:
|
||||
motion-dom: 12.23.23
|
||||
@@ -4031,12 +4395,53 @@ snapshots:
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
function-bind@1.1.2: {}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-define-property: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
es-object-atoms: 1.1.1
|
||||
function-bind: 1.1.2
|
||||
get-proto: 1.0.1
|
||||
gopd: 1.2.0
|
||||
has-symbols: 1.1.0
|
||||
hasown: 2.0.2
|
||||
math-intrinsics: 1.1.0
|
||||
|
||||
get-nonce@1.0.1: {}
|
||||
|
||||
get-proto@1.0.1:
|
||||
dependencies:
|
||||
dunder-proto: 1.0.1
|
||||
es-object-atoms: 1.1.1
|
||||
|
||||
glob-to-regexp@0.4.1: {}
|
||||
|
||||
glob@11.1.0:
|
||||
dependencies:
|
||||
foreground-child: 3.3.1
|
||||
jackspeak: 4.1.1
|
||||
minimatch: 10.1.1
|
||||
minipass: 7.1.2
|
||||
package-json-from-dist: 1.0.1
|
||||
path-scurry: 2.0.1
|
||||
|
||||
gopd@1.2.0: {}
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
has-symbols@1.1.0: {}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
dependencies:
|
||||
has-symbols: 1.1.0
|
||||
|
||||
hasown@2.0.2:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
|
||||
immer@10.2.0: {}
|
||||
|
||||
input-otp@1.4.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
||||
@@ -4048,8 +4453,14 @@ snapshots:
|
||||
|
||||
is-arrayish@0.3.2: {}
|
||||
|
||||
is-fullwidth-code-point@3.0.0: {}
|
||||
|
||||
isexe@2.0.0: {}
|
||||
|
||||
jackspeak@4.1.1:
|
||||
dependencies:
|
||||
'@isaacs/cliui': 8.0.2
|
||||
|
||||
jiti@2.6.1: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
@@ -4109,6 +4520,8 @@ snapshots:
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
|
||||
lru-cache@11.2.2: {}
|
||||
|
||||
lucide-react@0.553.0(react@19.2.0):
|
||||
dependencies:
|
||||
react: 19.2.0
|
||||
@@ -4117,6 +4530,14 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
mime-db@1.52.0: {}
|
||||
|
||||
mime-types@2.1.35:
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
|
||||
mime@3.0.0: {}
|
||||
|
||||
miniflare@4.20251109.0:
|
||||
@@ -4137,6 +4558,12 @@ snapshots:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
minimatch@10.1.1:
|
||||
dependencies:
|
||||
'@isaacs/brace-expansion': 5.0.0
|
||||
|
||||
minipass@7.1.2: {}
|
||||
|
||||
motion-dom@12.23.23:
|
||||
dependencies:
|
||||
motion-utils: 12.23.6
|
||||
@@ -4183,8 +4610,15 @@ snapshots:
|
||||
|
||||
object-assign@4.1.1: {}
|
||||
|
||||
package-json-from-dist@1.0.1: {}
|
||||
|
||||
path-key@3.1.1: {}
|
||||
|
||||
path-scurry@2.0.1:
|
||||
dependencies:
|
||||
lru-cache: 11.2.2
|
||||
minipass: 7.1.2
|
||||
|
||||
path-to-regexp@6.3.0: {}
|
||||
|
||||
pathe@2.0.3: {}
|
||||
@@ -4225,6 +4659,8 @@ snapshots:
|
||||
object-assign: 4.1.1
|
||||
react-is: 16.13.1
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
radix-ui@1.4.3(@types/react-dom@19.2.3(@types/react@19.2.5))(@types/react@19.2.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
||||
dependencies:
|
||||
'@radix-ui/primitive': 1.1.3
|
||||
@@ -4386,6 +4822,11 @@ snapshots:
|
||||
|
||||
reselect@5.1.1: {}
|
||||
|
||||
rimraf@6.1.0:
|
||||
dependencies:
|
||||
glob: 11.1.0
|
||||
package-json-from-dist: 1.0.1
|
||||
|
||||
scheduler@0.27.0: {}
|
||||
|
||||
semver@7.7.3: {}
|
||||
@@ -4454,6 +4895,8 @@ snapshots:
|
||||
|
||||
shebang-regex@3.0.0: {}
|
||||
|
||||
signal-exit@4.1.0: {}
|
||||
|
||||
simple-swizzle@0.2.2:
|
||||
dependencies:
|
||||
is-arrayish: 0.3.2
|
||||
@@ -4467,6 +4910,26 @@ snapshots:
|
||||
|
||||
stoppable@1.1.0: {}
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
string-width@5.1.2:
|
||||
dependencies:
|
||||
eastasianwidth: 0.2.0
|
||||
emoji-regex: 9.2.2
|
||||
strip-ansi: 7.1.2
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
|
||||
strip-ansi@7.1.2:
|
||||
dependencies:
|
||||
ansi-regex: 6.2.2
|
||||
|
||||
styled-jsx@5.1.6(react@19.2.0):
|
||||
dependencies:
|
||||
client-only: 0.0.1
|
||||
@@ -4488,6 +4951,8 @@ snapshots:
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
tunnel@0.0.6: {}
|
||||
|
||||
tw-animate-css@1.4.0: {}
|
||||
|
||||
typescript@5.9.3: {}
|
||||
@@ -4545,6 +5010,11 @@ snapshots:
|
||||
d3-time: 3.1.0
|
||||
d3-timer: 3.0.1
|
||||
|
||||
wcwidth@1.0.1:
|
||||
dependencies:
|
||||
defaults: 1.0.4
|
||||
optional: true
|
||||
|
||||
web-vitals@4.2.4: {}
|
||||
|
||||
which@2.0.2:
|
||||
@@ -4575,6 +5045,18 @@ snapshots:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
wrap-ansi@8.1.0:
|
||||
dependencies:
|
||||
ansi-styles: 6.2.3
|
||||
string-width: 5.1.2
|
||||
strip-ansi: 7.1.2
|
||||
|
||||
ws@8.18.0: {}
|
||||
|
||||
youch-core@0.3.3:
|
||||
|
||||
@@ -8,15 +8,6 @@ import { getCommunityGalleryRecord, getCommunitySubmissionByName, getCommunitySu
|
||||
export const dynamicParams = false
|
||||
export const revalidate = 21600 // 6 hours
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const icons = await getCommunitySubmissions()
|
||||
return icons
|
||||
.filter((icon) => icon.name)
|
||||
.map((icon) => ({
|
||||
icon: icon.name,
|
||||
}))
|
||||
}
|
||||
|
||||
type Props = {
|
||||
params: Promise<{ icon: string }>
|
||||
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
|
||||
@@ -49,8 +40,10 @@ export async function generateMetadata({ params }: Props, _parent: ResolvingMeta
|
||||
.join(" ")
|
||||
|
||||
const mainIconUrl =
|
||||
typeof iconData.data.base === "string" && iconData.data.base.startsWith("http") ? iconData.data.base : `${BASE_URL}/svg/${icon}.svg`
|
||||
|
||||
typeof iconData.data.base === "string" &&
|
||||
iconData.data.base.startsWith("http")
|
||||
? iconData.data.base
|
||||
: (iconData.data as any).mainIconUrl || `${BASE_URL}/svg/${icon}.svg`;
|
||||
return {
|
||||
title: `${formattedIconName} Icon (Community) | Dashboard Icons`,
|
||||
description: `Download the ${formattedIconName} community-submitted icon. Part of a collection of ${totalIcons} community icons awaiting review and addition to the Dashboard Icons collection.`,
|
||||
@@ -86,26 +79,16 @@ export async function generateMetadata({ params }: Props, _parent: ResolvingMeta
|
||||
type: "website",
|
||||
url: pageUrl,
|
||||
siteName: "Dashboard Icons",
|
||||
images: [
|
||||
{
|
||||
url: mainIconUrl,
|
||||
width: 512,
|
||||
height: 512,
|
||||
alt: `${formattedIconName} icon`,
|
||||
type: typeof mainIconUrl === "string" && mainIconUrl.endsWith(".png") ? "image/png" : typeof mainIconUrl === "string" && mainIconUrl.endsWith(".svg") ? "image/svg+xml" : "image/png",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: `${formattedIconName} Icon (Community) | Dashboard Icons`,
|
||||
description: `Download the ${formattedIconName} community-submitted icon. Part of a collection of ${totalIcons} community icons awaiting review and addition to the Dashboard Icons collection.`,
|
||||
images: [mainIconUrl],
|
||||
},
|
||||
alternates: {
|
||||
canonical: `${WEB_URL}/community/${icon}`,
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default async function CommunityIconPage({ params }: { params: Promise<{ icon: string }> }) {
|
||||
|
||||
@@ -38,8 +38,7 @@ export async function generateMetadata({ params, searchParams }: Props, _parent:
|
||||
const formattedIconName = icon
|
||||
.split("-")
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(" ")
|
||||
|
||||
.join(" ");
|
||||
return {
|
||||
title: `${formattedIconName} Icon | Dashboard Icons`,
|
||||
description: `Download the ${formattedIconName} icon in SVG, PNG, and WEBP formats for FREE. Part of a collection of ${totalIcons} curated icons for services, applications and tools, designed specifically for dashboards and app directories.`,
|
||||
|
||||
@@ -187,7 +187,41 @@ export function AdvancedIconSubmissionFormTanStack() {
|
||||
extras: extras,
|
||||
}
|
||||
|
||||
await pb.collection("submissions").create(submissionData)
|
||||
const record = await pb.collection("submissions").create(submissionData)
|
||||
|
||||
// Update extras with real filenames from PocketBase response
|
||||
// PocketBase sanitizes and renames files, so we need to update our references
|
||||
if (record.assets && record.assets.length > 0) {
|
||||
const updatedExtras = JSON.parse(JSON.stringify(extras))
|
||||
let assetIndex = 0
|
||||
|
||||
// Skip base icon (first asset) as we track it by 'base' format string only
|
||||
assetIndex++
|
||||
|
||||
if (value.files.dark?.[0] && updatedExtras.colors) {
|
||||
updatedExtras.colors.dark = record.assets[assetIndex]
|
||||
assetIndex++
|
||||
}
|
||||
|
||||
if (value.files.light?.[0] && updatedExtras.colors) {
|
||||
updatedExtras.colors.light = record.assets[assetIndex]
|
||||
assetIndex++
|
||||
}
|
||||
|
||||
if (value.files.wordmark?.[0] && updatedExtras.wordmark) {
|
||||
updatedExtras.wordmark.light = record.assets[assetIndex]
|
||||
assetIndex++
|
||||
}
|
||||
|
||||
if (value.files.wordmark_dark?.[0] && updatedExtras.wordmark) {
|
||||
updatedExtras.wordmark.dark = record.assets[assetIndex]
|
||||
assetIndex++
|
||||
}
|
||||
|
||||
await pb.collection("submissions").update(record.id, {
|
||||
extras: updatedExtras,
|
||||
})
|
||||
}
|
||||
|
||||
// Revalidate Next.js cache for community pages
|
||||
await revalidateAllSubmissions()
|
||||
|
||||
@@ -20,6 +20,7 @@ export function IconCard({ name, data: iconData, matchedAlias }: { name: string;
|
||||
src={imageUrl}
|
||||
alt={`${name} icon`}
|
||||
fill
|
||||
sizes="32px 32px"
|
||||
className="object-contain p-1 group-hover:scale-110 transition-transform duration-300"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -140,29 +140,67 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
const mainIconUrl = (iconData as any).mainIconUrl || (isCommunityIcon ? iconData.base : null)
|
||||
const assetUrls = (iconData as any).assetUrls || []
|
||||
|
||||
const getAvailableFormats = () => {
|
||||
const shouldShowBaseIcon = () => {
|
||||
if (!iconData.colors) return true;
|
||||
|
||||
// For regular icons, check if base icon name matches any variant name
|
||||
if (!isCommunityIcon) {
|
||||
const darkIconName = iconData.colors.dark;
|
||||
const lightIconName = iconData.colors.light;
|
||||
|
||||
// Don't show base icon if it's the same as dark or light variant
|
||||
if (icon === darkIconName || icon === lightIconName) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// For community icons, check if base icon matches any variant
|
||||
if (isCommunityIcon && mainIconUrl && assetUrls.length > 0) {
|
||||
// Find the actual URLs for dark and light variants
|
||||
const darkFilename = iconData.colors.dark;
|
||||
const lightFilename = iconData.colors.light;
|
||||
|
||||
const darkUrl = darkFilename
|
||||
? assetUrls.find((url: string) => url.includes(darkFilename))
|
||||
: null;
|
||||
const lightUrl = lightFilename
|
||||
? assetUrls.find((url: string) => url.includes(lightFilename))
|
||||
: null;
|
||||
|
||||
// Don't show base icon if it's the same as dark or light variant
|
||||
if (mainIconUrl === darkUrl || mainIconUrl === lightUrl) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const getAvailableFormats = (): string[] => {
|
||||
if (isCommunityIcon) {
|
||||
if (assetUrls.length > 0) {
|
||||
return assetUrls.map((url: string) => {
|
||||
const ext = url.split(".").pop()?.toLowerCase() || "svg"
|
||||
return ext === "svg" ? "svg" : ext === "png" ? "png" : "webp"
|
||||
})
|
||||
const formats = assetUrls.map((url: string) => {
|
||||
const ext = url.split(".").pop()?.toLowerCase() || "svg";
|
||||
return ext === "svg" ? "svg" : ext === "png" ? "png" : "webp";
|
||||
});
|
||||
// Deduplicate formats to avoid duplicate keys
|
||||
return Array.from(new Set(formats));
|
||||
}
|
||||
if (mainIconUrl) {
|
||||
const ext = mainIconUrl.split(".").pop()?.toLowerCase() || "svg"
|
||||
return [ext === "svg" ? "svg" : ext === "png" ? "png" : "webp"]
|
||||
const ext = mainIconUrl.split(".").pop()?.toLowerCase() || "svg";
|
||||
return [ext === "svg" ? "svg" : ext === "png" ? "png" : "webp"];
|
||||
}
|
||||
return ["svg"]
|
||||
return ["svg"];
|
||||
}
|
||||
switch (iconData.base) {
|
||||
case "svg":
|
||||
return ["svg", "png", "webp"]
|
||||
return ["svg", "png", "webp"];
|
||||
case "png":
|
||||
return ["png", "webp"]
|
||||
return ["png", "webp"];
|
||||
default:
|
||||
return [iconData.base]
|
||||
return [String(iconData.base)];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const availableFormats = getAvailableFormats()
|
||||
const [copiedVariants, _setCopiedVariants] = useState<Record<string, boolean>>({})
|
||||
@@ -324,7 +362,29 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
|
||||
if (isCommunityIcon && mainIconUrl) {
|
||||
const formatExt = format === "svg" ? "svg" : format === "png" ? "png" : "webp"
|
||||
const matchingUrl = assetUrls.find((url: string) => url.toLowerCase().endsWith(`.${formatExt}`))
|
||||
|
||||
// Try to find a specific asset URL that matches the requested variant filename
|
||||
// This is important because assetUrls contains all variants (base, dark, light)
|
||||
let matchingUrl: string | undefined;
|
||||
|
||||
if (theme && iconName && iconName !== icon) {
|
||||
// If a theme is specified, iconName holds the specific filename for that variant
|
||||
matchingUrl = assetUrls.find(
|
||||
(url: string) =>
|
||||
url.includes(iconName) &&
|
||||
url.toLowerCase().endsWith(`.${formatExt}`),
|
||||
);
|
||||
}
|
||||
|
||||
if (!matchingUrl) {
|
||||
// Fallback: find any asset with the matching extension
|
||||
matchingUrl = assetUrls.find((url: string) =>
|
||||
url.toLowerCase().endsWith(`.${formatExt}`),
|
||||
);
|
||||
}
|
||||
|
||||
const variantKey = `${format}-${theme || "default"}`;
|
||||
|
||||
imageUrl = matchingUrl || mainIconUrl
|
||||
githubUrl = ""
|
||||
} else {
|
||||
@@ -376,6 +436,7 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
src={imageUrl}
|
||||
alt={`${iconName} in ${format} format${theme ? ` (${theme} theme)` : ""}`}
|
||||
fill
|
||||
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
||||
loading="eager"
|
||||
priority
|
||||
className="object-contain p-4"
|
||||
@@ -404,7 +465,7 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
</div>
|
||||
</MagicCard>
|
||||
</TooltipProvider>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const formatedIconName = formatIconName(icon)
|
||||
@@ -442,15 +503,25 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="text-sm">
|
||||
<span className="font-medium">Updated on:</span> <time dateTime={iconData.update.timestamp}>{formattedDate}</time>
|
||||
<span className="font-medium">Updated on:</span>{" "}
|
||||
<time dateTime={iconData.update.timestamp}>
|
||||
{formattedDate}
|
||||
</time>
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="text-sm font-medium">By:</p>
|
||||
<Avatar className="h-5 w-5 border">
|
||||
<AvatarImage src={authorData.avatar_url} alt={`${authorName}'s avatar`} />
|
||||
<AvatarFallback>{authorName ? authorName.slice(0, 2).toUpperCase() : "??"}</AvatarFallback>
|
||||
<AvatarImage
|
||||
src={authorData.avatar_url}
|
||||
alt={`${authorName}'s avatar`}
|
||||
/>
|
||||
<AvatarFallback>
|
||||
{authorName
|
||||
? authorName.slice(0, 2).toUpperCase()
|
||||
: "??"}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
{authorData.html_url && (
|
||||
<Link
|
||||
@@ -462,7 +533,9 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
{authorName}
|
||||
</Link>
|
||||
)}
|
||||
{!authorData.html_url && <span className="text-sm">{authorName}</span>}
|
||||
{!authorData.html_url && (
|
||||
<span className="text-sm">{authorName}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -470,17 +543,26 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
|
||||
{iconData.categories && iconData.categories.length > 0 && (
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Categories</h3>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">
|
||||
Categories
|
||||
</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{iconData.categories.map((category) => (
|
||||
<Link key={category} href={`/icons?category=${encodeURIComponent(category)}`} className="cursor-pointer">
|
||||
<Link
|
||||
key={category}
|
||||
href={`/icons?category=${encodeURIComponent(category)}`}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="inline-flex items-center border border-primary/20 hover:border-primary px-2.5 py-0.5 text-sm"
|
||||
>
|
||||
{category
|
||||
.split("-")
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.map(
|
||||
(word) =>
|
||||
word.charAt(0).toUpperCase() + word.slice(1),
|
||||
)
|
||||
.join(" ")}
|
||||
</Badge>
|
||||
</Link>
|
||||
@@ -491,7 +573,9 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
|
||||
{iconData.aliases && iconData.aliases.length > 0 && (
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Aliases</h3>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">
|
||||
Aliases
|
||||
</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{iconData.aliases.map((alias) => (
|
||||
<Badge
|
||||
@@ -508,20 +592,25 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
)}
|
||||
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">About this icon</h3>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">
|
||||
About this icon
|
||||
</h3>
|
||||
<div className="text-xs text-muted-foreground space-y-2">
|
||||
<p>
|
||||
Available in{" "}
|
||||
{availableFormats.length > 1
|
||||
? `${availableFormats.length} formats (${availableFormats.map((f: string) => f.toUpperCase()).join(", ")}) `
|
||||
? `${availableFormats.length} formats (${availableFormats.map((f) => f.toUpperCase()).join(", ")}) `
|
||||
: `${availableFormats[0].toUpperCase()} format `}
|
||||
with a base format of {iconData.base.toUpperCase()}.
|
||||
{iconData.colors && " Includes both light and dark theme variants for better integration with different UI designs."}
|
||||
{iconData.wordmark && " Wordmark variants are also available for enhanced branding options."}
|
||||
{iconData.colors &&
|
||||
" Includes both light and dark theme variants for better integration with different UI designs."}
|
||||
{iconData.wordmark &&
|
||||
" Wordmark variants are also available for enhanced branding options."}
|
||||
</p>
|
||||
<p>
|
||||
Perfect for adding to dashboards, app directories, documentation, or anywhere you need the {formatIconName(icon)}{" "}
|
||||
logo.
|
||||
Perfect for adding to dashboards, app directories,
|
||||
documentation, or anywhere you need the{" "}
|
||||
{formatIconName(icon)} logo.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -536,14 +625,16 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
<CardTitle>
|
||||
<h2>Icon variants</h2>
|
||||
</CardTitle>
|
||||
<CardDescription>Click on any icon to copy its URL to your clipboard</CardDescription>
|
||||
<CardDescription>
|
||||
Click on any icon to copy its URL to your clipboard
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-10">
|
||||
{!iconData.colors && (
|
||||
{shouldShowBaseIcon() && (
|
||||
<IconVariantsSection
|
||||
title="Default"
|
||||
description="Standard icon versions. Click to copy URL."
|
||||
title="Base Icon"
|
||||
description="Original icon version. Click to copy URL."
|
||||
iconElement={<FileType className="w-4 h-4 text-blue-500" />}
|
||||
aavailableFormats={availableFormats}
|
||||
icon={icon}
|
||||
@@ -555,36 +646,36 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
/>
|
||||
)}
|
||||
|
||||
{iconData.colors && (
|
||||
<>
|
||||
<IconVariantsSection
|
||||
title="Light theme"
|
||||
description="Icon variants optimized for light backgrounds (typically lighter icon colors). Click to copy URL."
|
||||
iconElement={<Sun className="w-4 h-4 text-amber-500" />}
|
||||
aavailableFormats={availableFormats}
|
||||
icon={icon}
|
||||
theme="light"
|
||||
iconData={iconData}
|
||||
handleCopy={handleCopyUrl}
|
||||
handleDownload={handleDownload}
|
||||
copiedVariants={copiedVariants}
|
||||
renderVariant={renderVariant}
|
||||
/>
|
||||
{iconData.colors?.light && (
|
||||
<IconVariantsSection
|
||||
title="Light theme"
|
||||
description="Icon variants optimized for light backgrounds (typically lighter icon colors). Click to copy URL."
|
||||
iconElement={<Sun className="w-4 h-4 text-amber-500" />}
|
||||
aavailableFormats={availableFormats}
|
||||
icon={icon}
|
||||
theme="light"
|
||||
iconData={iconData}
|
||||
handleCopy={handleCopyUrl}
|
||||
handleDownload={handleDownload}
|
||||
copiedVariants={copiedVariants}
|
||||
renderVariant={renderVariant}
|
||||
/>
|
||||
)}
|
||||
|
||||
<IconVariantsSection
|
||||
title="Dark theme"
|
||||
description="Icon variants optimized for dark backgrounds (typically darker icon colors). Click to copy URL."
|
||||
iconElement={<Moon className="w-4 h-4 text-indigo-500" />}
|
||||
aavailableFormats={availableFormats}
|
||||
icon={icon}
|
||||
theme="dark"
|
||||
iconData={iconData}
|
||||
handleCopy={handleCopyUrl}
|
||||
handleDownload={handleDownload}
|
||||
copiedVariants={copiedVariants}
|
||||
renderVariant={renderVariant}
|
||||
/>
|
||||
</>
|
||||
{iconData.colors?.dark && (
|
||||
<IconVariantsSection
|
||||
title="Dark theme"
|
||||
description="Icon variants optimized for dark backgrounds (typically darker icon colors). Click to copy URL."
|
||||
iconElement={<Moon className="w-4 h-4 text-indigo-500" />}
|
||||
aavailableFormats={availableFormats}
|
||||
icon={icon}
|
||||
theme="dark"
|
||||
iconData={iconData}
|
||||
handleCopy={handleCopyUrl}
|
||||
handleDownload={handleDownload}
|
||||
copiedVariants={copiedVariants}
|
||||
renderVariant={renderVariant}
|
||||
/>
|
||||
)}
|
||||
|
||||
{iconData.wordmark && (
|
||||
@@ -612,25 +703,36 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
<div className="space-y-6">
|
||||
{status && statusDisplayName && statusColor && (
|
||||
<div className="">
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Status</h3>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">
|
||||
Status
|
||||
</h3>
|
||||
<Badge variant="outline" className={statusColor}>
|
||||
{statusDisplayName}
|
||||
</Badge>
|
||||
</div>
|
||||
)}
|
||||
<div className="">
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Base format</h3>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">
|
||||
Base format
|
||||
</h3>
|
||||
<div className="flex items-center gap-2">
|
||||
<FileType className="w-4 h-4 text-blue-500" />
|
||||
<div className="px-3 py-1.5 border border-border rounded-lg text-sm font-medium">{iconData.base.toUpperCase()}</div>
|
||||
<div className="px-3 py-1.5 border border-border rounded-lg text-sm font-medium">
|
||||
{iconData.base.toUpperCase()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Available formats</h3>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">
|
||||
Available formats
|
||||
</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{availableFormats.map((format: string) => (
|
||||
<div key={format} className="px-3 py-1.5 border border-border rounded-lg text-xs font-medium">
|
||||
<div
|
||||
key={format}
|
||||
className="px-3 py-1.5 border border-border rounded-lg text-xs font-medium"
|
||||
>
|
||||
{format.toUpperCase()}
|
||||
</div>
|
||||
))}
|
||||
@@ -639,35 +741,53 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
|
||||
{iconData.colors && (
|
||||
<div className="">
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Color variants</h3>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">
|
||||
Color variants
|
||||
</h3>
|
||||
<div className="space-y-2">
|
||||
{Object.entries(iconData.colors).map(([theme, variant]) => (
|
||||
<div key={theme} className="flex items-center gap-2">
|
||||
<PaletteIcon className="w-4 h-4 text-purple-500" />
|
||||
<span className="capitalize font-medium text-sm">{theme}:</span>
|
||||
<code className=" border border-border px-2 py-0.5 rounded-lg text-xs">{variant}</code>
|
||||
</div>
|
||||
))}
|
||||
{Object.entries(iconData.colors).map(
|
||||
([theme, variant]) => (
|
||||
<div key={theme} className="flex items-center gap-2">
|
||||
<PaletteIcon className="w-4 h-4 text-purple-500" />
|
||||
<span className="capitalize font-medium text-sm">
|
||||
{theme}:
|
||||
</span>
|
||||
<code className=" border border-border px-2 py-0.5 rounded-lg text-xs">
|
||||
{variant}
|
||||
</code>
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{iconData.wordmark && (
|
||||
<div className="">
|
||||
<h3 className="text-sm font-semibold text-muted-foreground">Wordmark variants</h3>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground">
|
||||
Wordmark variants
|
||||
</h3>
|
||||
<div className="space-y-2">
|
||||
{iconData.wordmark.light && (
|
||||
<div className="flex items-center gap-2">
|
||||
<Type className="w-4 h-4 text-green-500" />
|
||||
<span className="capitalize font-medium text-sm">Light:</span>
|
||||
<code className="border border-border px-2 py-0.5 rounded-lg text-xs">{iconData.wordmark.light}</code>
|
||||
<span className="capitalize font-medium text-sm">
|
||||
Light:
|
||||
</span>
|
||||
<code className="border border-border px-2 py-0.5 rounded-lg text-xs">
|
||||
{iconData.wordmark.light}
|
||||
</code>
|
||||
</div>
|
||||
)}
|
||||
{iconData.wordmark.dark && (
|
||||
<div className="flex items-center gap-2">
|
||||
<Type className="w-4 h-4 text-green-500" />
|
||||
<span className="capitalize font-medium text-sm">Dark:</span>
|
||||
<code className="border border-border px-2 py-0.5 rounded-lg text-xs">{iconData.wordmark.dark}</code>
|
||||
<span className="capitalize font-medium text-sm">
|
||||
Dark:
|
||||
</span>
|
||||
<code className="border border-border px-2 py-0.5 rounded-lg text-xs">
|
||||
{iconData.wordmark.dark}
|
||||
</code>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -676,9 +796,15 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
|
||||
{!isCommunityIcon && (
|
||||
<div className="">
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">Source</h3>
|
||||
<h3 className="text-sm font-semibold text-muted-foreground mb-2">
|
||||
Source
|
||||
</h3>
|
||||
<Button variant="outline" className="w-full" asChild>
|
||||
<Link href={`${REPO_PATH}/blob/main/meta/${icon}.json`} target="_blank" rel="noopener noreferrer">
|
||||
<Link
|
||||
href={`${REPO_PATH}/blob/main/meta/${icon}.json`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Github className="w-4 h-4 mr-2" />
|
||||
View on GitHub
|
||||
</Link>
|
||||
@@ -694,30 +820,41 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
{iconData.categories &&
|
||||
iconData.categories.length > 0 &&
|
||||
(() => {
|
||||
const MAX_RELATED_ICONS = 16
|
||||
const currentCategories = iconData.categories || []
|
||||
const MAX_RELATED_ICONS = 16;
|
||||
const currentCategories = iconData.categories || [];
|
||||
|
||||
const relatedIconsWithScore = Object.entries(allIcons)
|
||||
.map(([name, data]) => {
|
||||
if (name === icon) return null // Exclude the current icon
|
||||
if (name === icon) return null; // Exclude the current icon
|
||||
|
||||
const otherCategories = data.categories || []
|
||||
const commonCategories = currentCategories.filter((cat) => otherCategories.includes(cat))
|
||||
const score = commonCategories.length
|
||||
const otherCategories = data.categories || [];
|
||||
const commonCategories = currentCategories.filter((cat) =>
|
||||
otherCategories.includes(cat),
|
||||
);
|
||||
const score = commonCategories.length;
|
||||
|
||||
return score > 0 ? { name, data, score } : null
|
||||
return score > 0 ? { name, data, score } : null;
|
||||
})
|
||||
.filter((item): item is { name: string; data: Icon; score: number } => item !== null) // Type guard
|
||||
.sort((a, b) => b.score - a.score) // Sort by score DESC
|
||||
.filter(
|
||||
(item): item is { name: string; data: Icon; score: number } =>
|
||||
item !== null,
|
||||
) // Type guard
|
||||
.sort((a, b) => b.score - a.score); // Sort by score DESC
|
||||
|
||||
const topRelatedIcons = relatedIconsWithScore.slice(0, MAX_RELATED_ICONS)
|
||||
const topRelatedIcons = relatedIconsWithScore.slice(
|
||||
0,
|
||||
MAX_RELATED_ICONS,
|
||||
);
|
||||
|
||||
const viewMoreUrl = `/icons?${currentCategories.map((cat) => `category=${encodeURIComponent(cat)}`).join("&")}`
|
||||
const viewMoreUrl = `/icons?${currentCategories.map((cat) => `category=${encodeURIComponent(cat)}`).join("&")}`;
|
||||
|
||||
if (topRelatedIcons.length === 0) return null
|
||||
if (topRelatedIcons.length === 0) return null;
|
||||
|
||||
return (
|
||||
<section className="container mx-auto mt-12" aria-labelledby="related-icons-title">
|
||||
<section
|
||||
className="container mx-auto mt-12"
|
||||
aria-labelledby="related-icons-title"
|
||||
>
|
||||
<Card className="bg-background/50 border shadow-lg">
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
@@ -725,11 +862,18 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
<h2 id="related-icons-title">Related Icons</h2>
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Other icons from {currentCategories.map((cat) => cat.replace(/-/g, " ")).join(", ")} categories
|
||||
Other icons from{" "}
|
||||
{currentCategories
|
||||
.map((cat) => cat.replace(/-/g, " "))
|
||||
.join(", ")}{" "}
|
||||
categories
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<IconsGrid filteredIcons={topRelatedIcons} matchedAliases={{}} />
|
||||
<IconsGrid
|
||||
filteredIcons={topRelatedIcons}
|
||||
matchedAliases={{}}
|
||||
/>
|
||||
{relatedIconsWithScore.length > MAX_RELATED_ICONS && (
|
||||
<div className="mt-6 text-center">
|
||||
<Button
|
||||
@@ -747,8 +891,8 @@ export function IconDetails({ icon, iconData, authorData, allIcons, status, stat
|
||||
</CardContent>
|
||||
</Card>
|
||||
</section>
|
||||
)
|
||||
);
|
||||
})()}
|
||||
</main>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -138,10 +138,14 @@ async function fetchCommunitySubmissions(): Promise<IconWithName[]> {
|
||||
* Revalidates every 21600 seconds (6 hours) to match page revalidate time
|
||||
* Can be invalidated on-demand using revalidateTag("community-gallery")
|
||||
*/
|
||||
export const getCommunitySubmissions = unstable_cache(fetchCommunitySubmissions, ["community-submissions-list"], {
|
||||
revalidate: 21600,
|
||||
tags: ["community-gallery"],
|
||||
})
|
||||
export const getCommunitySubmissions = unstable_cache(
|
||||
fetchCommunitySubmissions,
|
||||
["community-submissions-list-v2"],
|
||||
{
|
||||
revalidate: 21600,
|
||||
tags: ["community-gallery"],
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Fetch a single community submission by name (raw function)
|
||||
@@ -149,10 +153,17 @@ export const getCommunitySubmissions = unstable_cache(fetchCommunitySubmissions,
|
||||
*/
|
||||
async function fetchCommunitySubmissionByName(name: string): Promise<IconWithName | null> {
|
||||
try {
|
||||
const pb = createServerPB()
|
||||
const pb = createServerPB();
|
||||
|
||||
const record = await pb.collection("community_gallery").getFirstListItem<CommunityGallery>(`name="${name}"`)
|
||||
return transformGalleryToIcon(record)
|
||||
const record = await pb
|
||||
.collection("community_gallery")
|
||||
.getFirstListItem<CommunityGallery>(`name="${name}"`);
|
||||
const transformed = transformGalleryToIcon(record);
|
||||
console.log(
|
||||
`[Community] Fetched ${name}, colors:`,
|
||||
transformed.data.colors,
|
||||
);
|
||||
return transformed;
|
||||
} catch (error) {
|
||||
console.error(`Error fetching community submission ${name}:`, error)
|
||||
return null
|
||||
@@ -166,10 +177,14 @@ async function fetchCommunitySubmissionByName(name: string): Promise<IconWithNam
|
||||
* Cache key: community-submission-{name}
|
||||
*/
|
||||
export function getCommunitySubmissionByName(name: string): Promise<IconWithName | null> {
|
||||
return unstable_cache(async () => fetchCommunitySubmissionByName(name), [`community-submission-${name}`], {
|
||||
revalidate: 21600,
|
||||
tags: ["community-gallery", "community-submission"],
|
||||
})()
|
||||
return unstable_cache(
|
||||
async () => fetchCommunitySubmissionByName(name),
|
||||
[`community-submission-${name}-v2`],
|
||||
{
|
||||
revalidate: 21600,
|
||||
tags: ["community-gallery", "community-submission"],
|
||||
},
|
||||
)();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user