diff --git a/.husky/pre-push b/.husky/pre-push index 88c788e..262c1a4 100644 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -18,20 +18,6 @@ while read local_ref local_sha remote_ref remote_sha; do fi ;; *) - # 对于普通分支推送,检查最新 tag - LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null) - if [ $? -eq 0 ]; then - # 只校验以 "v" 开头的 tag - if [[ $LATEST_TAG == v* ]]; then - echo "🏷️ 检查最新的 tag: $LATEST_TAG" - node .husky/scripts/verifyTagVersion.js "$LATEST_TAG" - else - echo "ℹ️ 最新 tag ($LATEST_TAG) 不是版本 tag,跳过校验" - fi - else - echo "⚠️ 没有找到任何 tag,跳过版本校验" - fi - ;; esac done diff --git a/components.json b/components.json new file mode 100644 index 0000000..09b9b8c --- /dev/null +++ b/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://shadcn-vue.com/schema.json", + "style": "new-york", + "typescript": true, + "tailwind": { + "config": "", + "css": "src/style.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "composables": "@/composables" + }, + "registries": {} +} diff --git a/package.json b/package.json index bbd3758..402a81e 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "@vueuse/core": "^14.1.0", "axios": "^1.7.8", "canvas-confetti": "^1.9.3", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "dayjs": "^1.11.13", "dexie": "^4.2.1", "github-markdown-css": "^5.8.0", @@ -31,7 +33,9 @@ "markdown-it": "^14.1.0", "pinia": "^3.0.3", "pinia-plugin-persist": "^1.0.0", + "reka-ui": "^2.6.1", "sparticles": "^1.3.1", + "tailwind-merge": "^3.4.0", "three": "0.166.0", "three-css3d": "1.0.6", "uuid": "^13.0.0", @@ -84,6 +88,7 @@ "sass-loader": "^16.0.3", "tailwindcss": "^4.1.17", "terser": "^5.36.0", + "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", "unplugin-auto-import": "^20.1.0", "unplugin-icons": "^22.3.0", @@ -95,5 +100,6 @@ "vite-plugin-vue-devtools": "^8.0.2", "vitest": "^4.0.15", "vue-tsc": "^3.0.7" - } -} \ No newline at end of file + }, + "packageManager": "pnpm@10.8.1+sha1.a4eff733d0c4ccc179997f0ef4986f6e92427781" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 588e335..f80f2e6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,12 @@ importers: canvas-confetti: specifier: ^1.9.3 version: 1.9.3 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 dayjs: specifier: ^1.11.13 version: 1.11.13 @@ -47,9 +53,15 @@ importers: pinia-plugin-persist: specifier: ^1.0.0 version: 1.0.0(pinia@3.0.3(typescript@5.9.3)(vue@3.5.13(typescript@5.9.3)))(vue@3.5.13(typescript@5.9.3)) + reka-ui: + specifier: ^2.6.1 + version: 2.6.1(typescript@5.9.3)(vue@3.5.13(typescript@5.9.3)) sparticles: specifier: ^1.3.1 version: 1.3.1 + tailwind-merge: + specifier: ^3.4.0 + version: 3.4.0 three: specifier: 0.166.0 version: 0.166.0 @@ -201,6 +213,9 @@ importers: terser: specifier: ^5.36.0 version: 5.36.0 + tw-animate-css: + specifier: ^1.4.0 + version: 1.4.0 typescript: specifier: ~5.9.3 version: 5.9.3 @@ -1265,6 +1280,18 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + + '@floating-ui/vue@1.1.9': + resolution: {integrity: sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1297,6 +1324,12 @@ packages: '@iconify/utils@3.0.2': resolution: {integrity: sha512-EfJS0rLfVuRuJRn4psJHtK2A9TqVnkxPpHY6lYHiB9+8eSuudsxbwMiavocG45ujOo6FJ+CIRlRnlOGinzkaGQ==} + '@internationalized/date@3.10.0': + resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==} + + '@internationalized/number@3.6.5': + resolution: {integrity: sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==} + '@intlify/core-base@11.2.2': resolution: {integrity: sha512-0mCTBOLKIqFUP3BzwuFW23hYEl9g/wby6uY//AC5hTgQfTsM2srCYF2/hYGp+a5DZ/HIFIgKkLJMzXTt30r0JQ==} engines: {node: '>= 16'} @@ -1610,6 +1643,9 @@ packages: peerDependencies: eslint: '>=9.0.0' + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + '@tailwindcss/node@4.1.13': resolution: {integrity: sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==} @@ -1709,6 +1745,14 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 + '@tanstack/virtual-core@3.13.13': + resolution: {integrity: sha512-uQFoSdKKf5S8k51W5t7b2qpfkyIbdHMzAn+AMQvHPxKUPeo1SsGaA4JRISQT87jm28b7z8OEqPcg1IOZagQHcA==} + + '@tanstack/vue-virtual@3.13.13': + resolution: {integrity: sha512-Cf2xIEE8nWAfsX0N5nihkPYMeQRT+pHt4NEkuP8rNCn6lVnLDiV8rC8IeIxbKmQC0yPnj4SIBLwXYVf86xxKTQ==} + peerDependencies: + vue: ^2.7.0 || ^3.0.0 + '@tauri-apps/cli-darwin-arm64@2.9.5': resolution: {integrity: sha512-P5XDyCwq3VbWGAplyfP/bgmuUITVDcypxgZUyX45SM7HbU1Nrkk0cNK1HCOkuNBAVVbWen2GUNWah/AiupHHXg==} engines: {node: '>= 10'} @@ -2189,14 +2233,23 @@ packages: vue: optional: true + '@vueuse/core@12.8.2': + resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==} + '@vueuse/core@14.1.0': resolution: {integrity: sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==} peerDependencies: vue: ^3.5.0 + '@vueuse/metadata@12.8.2': + resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==} + '@vueuse/metadata@14.1.0': resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==} + '@vueuse/shared@12.8.2': + resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==} + '@vueuse/shared@14.1.0': resolution: {integrity: sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==} peerDependencies: @@ -2353,6 +2406,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} @@ -2584,6 +2641,9 @@ packages: resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} engines: {node: '>=0.10.0'} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + clean-regexp@1.0.0: resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} engines: {node: '>=4'} @@ -2596,6 +2656,10 @@ packages: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + codepage@1.15.0: resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} engines: {node: '>=0.8'} @@ -2829,6 +2893,9 @@ packages: resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} engines: {node: '>=0.10.0'} + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -4669,6 +4736,11 @@ packages: resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} hasBin: true + reka-ui@2.6.1: + resolution: {integrity: sha512-XK7cJDQoNuGXfCNzBBo/81Yg/OgjPwvbabnlzXG2VsdSgNsT6iIkuPBPr+C0Shs+3bb0x0lbPvgQAhMSCKm5Ww==} + peerDependencies: + vue: '>= 3.2.0' + repeat-element@1.1.4: resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} engines: {node: '>=0.10.0'} @@ -5034,6 +5106,9 @@ packages: systemjs@6.15.1: resolution: {integrity: sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==} + tailwind-merge@3.4.0: + resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} + tailwindcss@4.1.13: resolution: {integrity: sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==} @@ -5158,6 +5233,9 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tw-animate-css@1.4.0: + resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -5462,6 +5540,17 @@ packages: '@vue/composition-api': optional: true + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue-dompurify-html@5.2.0: resolution: {integrity: sha512-GX+BStkKEJ8wu/+hU1EK2nu/gzXWhb4XzBu6aowpsuU/3nkvXvZ2jx4nZ9M3jtS/Vu7J7MtFXjc7x3cWQ+zbVQ==} peerDependencies: @@ -6871,6 +6960,26 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/utils@0.2.10': {} + + '@floating-ui/vue@1.1.9(vue@3.5.13(typescript@5.9.3))': + dependencies: + '@floating-ui/dom': 1.7.4 + '@floating-ui/utils': 0.2.10 + vue-demi: 0.14.10(vue@3.5.13(typescript@5.9.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -6907,6 +7016,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@internationalized/date@3.10.0': + dependencies: + '@swc/helpers': 0.5.17 + + '@internationalized/number@3.6.5': + dependencies: + '@swc/helpers': 0.5.17 + '@intlify/core-base@11.2.2': dependencies: '@intlify/message-compiler': 11.2.2 @@ -7141,6 +7258,10 @@ snapshots: estraverse: 5.3.0 picomatch: 4.0.3 + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + '@tailwindcss/node@4.1.13': dependencies: '@jridgewell/remapping': 2.3.5 @@ -7220,6 +7341,13 @@ snapshots: tailwindcss: 4.1.13 vite: 7.1.6(@types/node@24.10.2)(jiti@2.5.1)(lightningcss@1.30.1)(sass@1.81.0)(terser@5.36.0)(yaml@2.8.2) + '@tanstack/virtual-core@3.13.13': {} + + '@tanstack/vue-virtual@3.13.13(vue@3.5.13(typescript@5.9.3))': + dependencies: + '@tanstack/virtual-core': 3.13.13 + vue: 3.5.13(typescript@5.9.3) + '@tauri-apps/cli-darwin-arm64@2.9.5': optional: true @@ -7830,6 +7958,15 @@ snapshots: typescript: 5.9.3 vue: 3.5.13(typescript@5.9.3) + '@vueuse/core@12.8.2(typescript@5.9.3)': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 12.8.2 + '@vueuse/shared': 12.8.2(typescript@5.9.3) + vue: 3.5.13(typescript@5.9.3) + transitivePeerDependencies: + - typescript + '@vueuse/core@14.1.0(vue@3.5.13(typescript@5.9.3))': dependencies: '@types/web-bluetooth': 0.0.21 @@ -7837,8 +7974,16 @@ snapshots: '@vueuse/shared': 14.1.0(vue@3.5.13(typescript@5.9.3)) vue: 3.5.13(typescript@5.9.3) + '@vueuse/metadata@12.8.2': {} + '@vueuse/metadata@14.1.0': {} + '@vueuse/shared@12.8.2(typescript@5.9.3)': + dependencies: + vue: 3.5.13(typescript@5.9.3) + transitivePeerDependencies: + - typescript + '@vueuse/shared@14.1.0(vue@3.5.13(typescript@5.9.3))': dependencies: vue: 3.5.13(typescript@5.9.3) @@ -8013,6 +8158,10 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + aria-query@5.1.3: dependencies: deep-equal: 2.2.3 @@ -8265,6 +8414,10 @@ snapshots: isobject: 3.0.1 static-extend: 0.1.2 + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + clean-regexp@1.0.0: dependencies: escape-string-regexp: 1.0.5 @@ -8277,6 +8430,8 @@ snapshots: clone@2.1.2: {} + clsx@2.1.1: {} + codepage@1.15.0: {} collection-visit@1.0.0: @@ -8492,6 +8647,8 @@ snapshots: is-descriptor: 1.0.3 isobject: 3.0.1 + defu@6.1.4: {} + delayed-stream@1.0.0: {} dequal@2.0.3: {} @@ -10534,6 +10691,23 @@ snapshots: dependencies: jsesc: 3.1.0 + reka-ui@2.6.1(typescript@5.9.3)(vue@3.5.13(typescript@5.9.3)): + dependencies: + '@floating-ui/dom': 1.7.4 + '@floating-ui/vue': 1.1.9(vue@3.5.13(typescript@5.9.3)) + '@internationalized/date': 3.10.0 + '@internationalized/number': 3.6.5 + '@tanstack/vue-virtual': 3.13.13(vue@3.5.13(typescript@5.9.3)) + '@vueuse/core': 12.8.2(typescript@5.9.3) + '@vueuse/shared': 12.8.2(typescript@5.9.3) + aria-hidden: 1.2.6 + defu: 6.1.4 + ohash: 2.0.11 + vue: 3.5.13(typescript@5.9.3) + transitivePeerDependencies: + - '@vue/composition-api' + - typescript + repeat-element@1.1.4: {} repeat-string@1.6.1: {} @@ -10897,6 +11071,8 @@ snapshots: systemjs@6.15.1: {} + tailwind-merge@3.4.0: {} + tailwindcss@4.1.13: {} tailwindcss@4.1.17: {} @@ -11008,6 +11184,8 @@ snapshots: tslib@2.8.1: {} + tw-animate-css@1.4.0: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -11321,6 +11499,10 @@ snapshots: dependencies: vue: 3.5.13(typescript@5.9.3) + vue-demi@0.14.10(vue@3.5.13(typescript@5.9.3)): + dependencies: + vue: 3.5.13(typescript@5.9.3) + vue-dompurify-html@5.2.0(vue@3.5.13(typescript@5.9.3)): dependencies: dompurify: 3.2.1 diff --git a/src/App.vue b/src/App.vue index c7b1087..1af3e37 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,19 +1,9 @@