mirror of
https://github.com/hpware/news-analyze.git
synced 2025-06-23 13:04:23 +00:00
refactor: remove GitHub authentication API endpoints and add new components
- Deleted GitHub callback and authentication handler files. - Added new component for displaying headlines. - Implemented hot news feed component with external API fetching. - Created dynamic news provider page with routing. - Developed news organization about page with animations and data fetching. - Introduced a code of conduct document.
This commit is contained in:
parent
b35e96625e
commit
930713042e
20 changed files with 861 additions and 599 deletions
17
.env.example
17
.env.example
|
@ -1,9 +1,12 @@
|
|||
S3_ACCESS_KEY=""
|
||||
S3_SECRET_KEY=""
|
||||
S3_BUCKETNAME=""
|
||||
S3_ENDPOINT=""
|
||||
|
||||
NUXT_GITHUB_CLIENT_ID=""
|
||||
NUXT_GITHUB_CLIENT_SECRET=""
|
||||
S3_ACCESS_KEY=
|
||||
S3_SECRET_KEY=
|
||||
S3_BUCKETNAME=
|
||||
S3_ENDPOINT=
|
||||
|
||||
POSTGRES_URL=""
|
||||
POSTGRES_URL=
|
||||
|
||||
GROQ_API_KEY=
|
||||
|
||||
NUXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
|
||||
NUXT_CLERK_SECRET_KEY=
|
1
CODE_OF_CONDUCT.md.md
Normal file
1
CODE_OF_CONDUCT.md.md
Normal file
|
@ -0,0 +1 @@
|
|||
# Code of conduct
|
|
@ -2,6 +2,8 @@
|
|||
|
||||

|
||||
|
||||
App Design: [Freeform](https://www.icloud.com/freeform/026AxB798cViZ9jJ2DkNsXUCQ#Untitled_5)
|
||||
|
||||
## Why?
|
||||
|
||||
我們使用這個新聞來舉例:
|
||||
|
|
41
bun.lock
41
bun.lock
|
@ -4,6 +4,7 @@
|
|||
"": {
|
||||
"name": "BlindSpec",
|
||||
"dependencies": {
|
||||
"@clerk/nuxt": "^1.6.3",
|
||||
"@fontsource-variable/noto-sans-tc": "^5.2.5",
|
||||
"@fontsource/fira-code": "^5.2.6",
|
||||
"@fontsource/fira-sans": "^5.2.5",
|
||||
|
@ -101,6 +102,16 @@
|
|||
|
||||
"@babel/types": ["@babel/types@7.27.1", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q=="],
|
||||
|
||||
"@clerk/backend": ["@clerk/backend@1.32.0", "", { "dependencies": { "@clerk/shared": "^3.8.2", "@clerk/types": "^4.58.0", "cookie": "1.0.2", "snakecase-keys": "8.0.1", "tslib": "2.8.1" }, "peerDependencies": { "svix": "^1.62.0" }, "optionalPeers": ["svix"] }, "sha512-D0hC2mnU79wM4q8GU5ZFrMD3p9lHy3aM+qDi9WqD3L40d65JJ+lzD+rKSqfM5/gDtUWUdD2Ezvqa0ZObRXTcgg=="],
|
||||
|
||||
"@clerk/nuxt": ["@clerk/nuxt@1.6.3", "", { "dependencies": { "@clerk/backend": "^1.32.0", "@clerk/shared": "^3.8.2", "@clerk/types": "^4.58.0", "@clerk/vue": "^1.8.0", "@nuxt/kit": "^3.16.2", "@nuxt/schema": "^3.16.2", "h3": "^1.15.1" } }, "sha512-6WjAuhXJ1MR3iNMyOKsGfdzarN58MvlPyXKdTVNo8pOPfo3Q0d+weGNbjLZrVtiT4t2OzvMbK2v/U78wYqf2gg=="],
|
||||
|
||||
"@clerk/shared": ["@clerk/shared@3.8.2", "", { "dependencies": { "@clerk/types": "^4.58.0", "dequal": "2.0.3", "glob-to-regexp": "0.4.1", "js-cookie": "3.0.5", "std-env": "^3.9.0", "swr": "^2.3.3" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" }, "optionalPeers": ["react", "react-dom"] }, "sha512-y8g8/wbFo/3gCRsrk2rmGQ1uzIb8lPM4Wjggt4glC8mPqTGgMFuIAK0Sj0PAJOq5739sokFXc4CzZdMnu/P5ug=="],
|
||||
|
||||
"@clerk/types": ["@clerk/types@4.58.0", "", { "dependencies": { "csstype": "3.1.3" } }, "sha512-P30Vnqaw2UzoSZivNG61NvF9WiAVbKItOvkVJzUbwqDkISdmNOio8mWCeFuKq+bxjPESvS+S615Uplm7dl6jpg=="],
|
||||
|
||||
"@clerk/vue": ["@clerk/vue@1.8.0", "", { "dependencies": { "@clerk/shared": "^3.8.2", "@clerk/types": "^4.58.0" }, "peerDependencies": { "vue": "^3.2.0" } }, "sha512-wfxlQMnMhRzjMF+ZKjEz3QINl9WUyLDI2FaIxFoegXdEESAv3301wxMDK+0gfV9d0xAqk0Aml62Nw72GRoYv+w=="],
|
||||
|
||||
"@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.0", "", { "dependencies": { "mime": "^3.0.0" } }, "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA=="],
|
||||
|
||||
"@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="],
|
||||
|
@ -843,7 +854,7 @@
|
|||
|
||||
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
||||
|
||||
"cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
|
||||
"cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
|
||||
|
||||
"cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="],
|
||||
|
||||
|
@ -937,6 +948,8 @@
|
|||
|
||||
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
||||
|
||||
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
|
||||
|
||||
"destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="],
|
||||
|
||||
"destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
|
||||
|
@ -977,6 +990,8 @@
|
|||
|
||||
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
|
||||
|
||||
"dot-case": ["dot-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w=="],
|
||||
|
||||
"dot-prop": ["dot-prop@9.0.0", "", { "dependencies": { "type-fest": "^4.18.2" } }, "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ=="],
|
||||
|
||||
"dotenv": ["dotenv@16.5.0", "", {}, "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg=="],
|
||||
|
@ -1187,6 +1202,8 @@
|
|||
|
||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||
|
||||
"glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="],
|
||||
|
||||
"global-directory": ["global-directory@4.0.1", "", { "dependencies": { "ini": "4.1.1" } }, "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q=="],
|
||||
|
||||
"globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
@ -1335,6 +1352,8 @@
|
|||
|
||||
"jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="],
|
||||
|
||||
"js-cookie": ["js-cookie@3.0.5", "", {}, "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw=="],
|
||||
|
||||
"js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
|
||||
|
||||
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
||||
|
@ -1449,6 +1468,8 @@
|
|||
|
||||
"logform": ["logform@2.7.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ=="],
|
||||
|
||||
"lower-case": ["lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg=="],
|
||||
|
||||
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||
|
||||
"lucide-vue-next": ["lucide-vue-next@0.508.0", "", { "peerDependencies": { "vue": ">=3.0.1" } }, "sha512-ZPO/Kh1gz7RU2/hd8FWw3SjLVMUIm/TJAhOGV9CbM1zvNwiJ8DK6W33LFWxtlZZ1IUPOXAny0pbttY+yyOsjKg=="],
|
||||
|
@ -1463,6 +1484,8 @@
|
|||
|
||||
"make-dir": ["make-dir@3.1.0", "", { "dependencies": { "semver": "^6.0.0" } }, "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw=="],
|
||||
|
||||
"map-obj": ["map-obj@4.3.0", "", {}, "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ=="],
|
||||
|
||||
"marky": ["marky@1.3.0", "", {}, "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ=="],
|
||||
|
||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||
|
@ -1549,6 +1572,8 @@
|
|||
|
||||
"nitropack": ["nitropack@2.11.11", "", { "dependencies": { "@cloudflare/kv-asset-handler": "^0.4.0", "@netlify/functions": "^3.1.2", "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@rollup/plugin-terser": "^0.4.4", "@vercel/nft": "^0.29.2", "archiver": "^7.0.1", "c12": "^3.0.3", "chokidar": "^4.0.3", "citty": "^0.1.6", "compatx": "^0.2.0", "confbox": "^0.2.2", "consola": "^3.4.2", "cookie-es": "^2.0.0", "croner": "^9.0.0", "crossws": "^0.3.4", "db0": "^0.3.2", "defu": "^6.1.4", "destr": "^2.0.5", "dot-prop": "^9.0.0", "esbuild": "^0.25.3", "escape-string-regexp": "^5.0.0", "etag": "^1.8.1", "exsolve": "^1.0.5", "globby": "^14.1.0", "gzip-size": "^7.0.0", "h3": "^1.15.3", "hookable": "^5.5.3", "httpxy": "^0.1.7", "ioredis": "^5.6.1", "jiti": "^2.4.2", "klona": "^2.0.6", "knitwork": "^1.2.0", "listhen": "^1.9.0", "magic-string": "^0.30.17", "magicast": "^0.3.5", "mime": "^4.0.7", "mlly": "^1.7.4", "node-fetch-native": "^1.6.6", "node-mock-http": "^1.0.0", "ofetch": "^1.4.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.1.0", "pretty-bytes": "^6.1.1", "radix3": "^1.1.2", "rollup": "^4.40.0", "rollup-plugin-visualizer": "^5.14.0", "scule": "^1.3.0", "semver": "^7.7.1", "serve-placeholder": "^2.0.2", "serve-static": "^2.2.0", "source-map": "^0.7.4", "std-env": "^3.9.0", "ufo": "^1.6.1", "ultrahtml": "^1.6.0", "uncrypto": "^0.1.3", "unctx": "^2.4.1", "unenv": "^2.0.0-rc.15", "unimport": "^5.0.0", "unplugin-utils": "^0.2.4", "unstorage": "^1.16.0", "untyped": "^2.0.0", "unwasm": "^0.3.9", "youch": "^4.1.0-beta.7", "youch-core": "^0.3.2" }, "peerDependencies": { "xml2js": "^0.6.2" }, "optionalPeers": ["xml2js"], "bin": { "nitro": "dist/cli/index.mjs", "nitropack": "dist/cli/index.mjs" } }, "sha512-KnWkajf2ZIsjr7PNeENvDRi87UdMrn8dRTe/D/Ak3Ud6sbC7ZCArVGeosoY7WZvsvLBN1YAwm//34Bq4dKkAaw=="],
|
||||
|
||||
"no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="],
|
||||
|
||||
"node-abi": ["node-abi@3.75.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg=="],
|
||||
|
||||
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
||||
|
@ -1829,6 +1854,8 @@
|
|||
|
||||
"rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
|
||||
|
||||
"react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="],
|
||||
|
||||
"read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
|
||||
|
||||
"read-package-up": ["read-package-up@11.0.0", "", { "dependencies": { "find-up-simple": "^1.0.0", "read-pkg": "^9.0.0", "type-fest": "^4.6.0" } }, "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ=="],
|
||||
|
@ -1947,6 +1974,10 @@
|
|||
|
||||
"smob": ["smob@1.5.0", "", {}, "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig=="],
|
||||
|
||||
"snake-case": ["snake-case@3.0.4", "", { "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg=="],
|
||||
|
||||
"snakecase-keys": ["snakecase-keys@8.0.1", "", { "dependencies": { "map-obj": "^4.1.0", "snake-case": "^3.0.4", "type-fest": "^4.15.0" } }, "sha512-Sj51kE1zC7zh6TDlNNz0/Jn1n5HiHdoQErxO8jLtnyrkJW/M5PrI7x05uDgY3BO7OUQYKCvmeMurW6BPUdwEOw=="],
|
||||
|
||||
"source-map": ["source-map@0.7.4", "", {}, "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
@ -2007,6 +2038,8 @@
|
|||
|
||||
"svgo": ["svgo@3.3.2", "", { "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0" }, "bin": "./bin/svgo" }, "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw=="],
|
||||
|
||||
"swr": ["swr@2.3.3", "", { "dependencies": { "dequal": "^2.0.3", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A=="],
|
||||
|
||||
"system-architecture": ["system-architecture@0.1.0", "", {}, "sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA=="],
|
||||
|
||||
"tailwind-config-viewer": ["tailwind-config-viewer@2.0.4", "", { "dependencies": { "@koa/router": "^12.0.1", "commander": "^6.0.0", "fs-extra": "^9.0.1", "koa": "^2.14.2", "koa-static": "^5.0.0", "open": "^7.0.4", "portfinder": "^1.0.26", "replace-in-file": "^6.1.0" }, "peerDependencies": { "tailwindcss": "1 || 2 || 2.0.1-compat || 3" }, "bin": { "tailwind-config-viewer": "cli/index.js", "tailwindcss-config-viewer": "cli/index.js" } }, "sha512-icvcmdMmt9dphvas8wL40qttrHwAnW3QEN4ExJ2zICjwRsPj7gowd1cOceaWG3IfTuM/cTNGQcx+bsjMtmV+cw=="],
|
||||
|
@ -2137,6 +2170,8 @@
|
|||
|
||||
"urlpattern-polyfill": ["urlpattern-polyfill@8.0.2", "", {}, "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ=="],
|
||||
|
||||
"use-sync-external-store": ["use-sync-external-store@1.5.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A=="],
|
||||
|
||||
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
||||
|
||||
"utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="],
|
||||
|
@ -2413,6 +2448,8 @@
|
|||
|
||||
"execa/@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="],
|
||||
|
||||
"express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
|
||||
|
||||
"externality/pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
|
||||
|
||||
"extract-zip/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
|
||||
|
@ -2593,8 +2630,6 @@
|
|||
|
||||
"yauzl/buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
|
||||
|
||||
"youch/cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
|
||||
|
||||
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||
|
||||
"@eslint/config-array/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
|
||||
|
|
|
@ -6,7 +6,7 @@ const localeLink = useLocalePath();
|
|||
class="flex flex-col justify-center align-center text-center absolute inset-x-0"
|
||||
>
|
||||
<span class="text-sm m-4 mb-0 text-center align-center justify-center"
|
||||
>{{ new Date().getFullYear() }} © yh</span
|
||||
>2025 - {{ new Date().getFullYear() }} © yh</span
|
||||
>
|
||||
<span class="text-xs mt-0 m-2 text-center align-center justify-center">
|
||||
Inspired by Ground.News
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"newsComparePlatform": "news comparison platform"
|
||||
},
|
||||
"startusing": "Let's Start!",
|
||||
"learnmore": "Learn More",
|
||||
"learnmore": "Learn More"
|
||||
},
|
||||
"dailybriefing": "Daily Briefing",
|
||||
"Welcome": "Welcome",
|
||||
|
|
|
@ -16,7 +16,8 @@ export default defineNuxtConfig({
|
|||
"@nuxtjs/i18n",
|
||||
"@nuxtjs/tailwindcss",
|
||||
"shadcn-nuxt",
|
||||
"motion-v/nuxt"
|
||||
"motion-v/nuxt",
|
||||
"@clerk/nuxt",
|
||||
],
|
||||
i18n: {
|
||||
defaultLocale: "en",
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
"start": "bun run .output/server/index.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@clerk/nuxt": "^1.6.3",
|
||||
"@fontsource-variable/noto-sans-tc": "^5.2.5",
|
||||
"@fontsource/fira-code": "^5.2.6",
|
||||
"@fontsource/fira-sans": "^5.2.5",
|
||||
|
|
|
@ -1,3 +1,73 @@
|
|||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: false,
|
||||
});
|
||||
import { gsap } from "gsap";
|
||||
import { TextPlugin } from "gsap/TextPlugin";
|
||||
gsap.registerPlugin(TextPlugin);
|
||||
const { t } = useI18n();
|
||||
const localePath = useLocalePath();
|
||||
const router = useRouter();
|
||||
const popMessage = ref(null);
|
||||
const currentDate = ref(
|
||||
new Date().toLocaleDateString("zh-TW", {
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
hour12: false,
|
||||
}),
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
setInterval(() => {
|
||||
currentDate.value = new Date().toLocaleDateString("zh-TW", {
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
hour12: false,
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
import { ComputerDesktopIcon } from "@heroicons/vue/24/outline";
|
||||
</script>
|
||||
<template>
|
||||
<h1>The "For you page"</h1>
|
||||
<div
|
||||
class="absolute inset-x-0 flex flex-row px-2 py-1 bg-white dark:bg-gray-900 justify-between align-center text-center z-index-[999999]"
|
||||
>
|
||||
<div class="flex flex-row g-2 text-gray-400 dark:text-gray-500">
|
||||
<button @click="" class="w-8 h-8 text-gray-400 dark:text-gray-500">
|
||||
<ComputerDesktopIcon class="w-8 h-8 text-gray-400 dark:text-gray-500" />
|
||||
</button>
|
||||
<span class="ml-1 mr-2 text-[20px]">|</span>
|
||||
</div>
|
||||
<div class="text-gray-400">{{ currentDate }}</div>
|
||||
</div>
|
||||
<div class="w-full h-[2.5em]"></div>
|
||||
<div
|
||||
class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-x-0 inset-y-0"
|
||||
>
|
||||
<div class="z-index-[9]"></div>
|
||||
</div>
|
||||
<div
|
||||
class="absolute w-[calc(100% - 5px)] inset-x-0 bottom-0 mx-[1.5px] p-3 z-index-[999999] justify-between align-center flex flex-row"
|
||||
>
|
||||
<div class="">
|
||||
Lang: <span class="text-sm">{{ $i18n.locale }}</span>
|
||||
</div>
|
||||
<div class="">
|
||||
<SignedOut>
|
||||
<SignInButton />
|
||||
</SignedOut>
|
||||
<SignedIn>
|
||||
<UserButton />
|
||||
</SignedIn>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -56,7 +56,7 @@ onMounted(() => {
|
|||
<div class="flex flex-row justify-center align-center gap-0s">
|
||||
<NuxtLink :to="localePath('/app/')">
|
||||
<button
|
||||
class="m-4 mr-1 ml-1 bg-[#8C9393] text-white p-3 rounded-full bg-gradient-to-l from-sky-500 to-purple-600 transition-all duration-150 hover:transform hover:scale-105 hover:shadow-lg"
|
||||
class="m-4 mr-1 ml-1 bg-[#8C9393] text-white p-3 rounded-[10px] bg-gradient-to-l from-sky-500 to-purple-600 transition-all duration-150 hover:transform hover:scale-105 hover:shadow-lg"
|
||||
>
|
||||
<span>{{ t("home.startusing") }}</span>
|
||||
</button>
|
||||
|
@ -73,15 +73,40 @@ onMounted(() => {
|
|||
<div class="h-screen"></div>
|
||||
<div id="learnmore"></div>
|
||||
<div class="flex flex-row flex-wrap justify-center gap-x-10 gap-y-3">
|
||||
<div class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]">
|
||||
<div
|
||||
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]"
|
||||
>
|
||||
<h1 class="text-8xl mt-0">🤔</h1>
|
||||
<h2 class="text-xl font-bold">Why?</h2>
|
||||
<span class="text-sm">台灣的新聞是要痲是來自中國控制的媒體,或是來自只想獲得點閱的記者。</span>
|
||||
<span class="text-sm"
|
||||
>台灣的新聞是要痲是來自中國控制的媒體,或是來自只想獲得點閱的記者。</span
|
||||
>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]">
|
||||
<div
|
||||
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]"
|
||||
>
|
||||
<h1 class="text-8xl mt-0">🧐</h1>
|
||||
<h2 class="text-xl font-bold">How?</h2>
|
||||
<span class="text-sm">We use web scraping to search for the latest news, and store it into a postgres database.</span>
|
||||
<span class="text-sm"
|
||||
>We use web scraping to search for the latest news, and store it into
|
||||
a postgres database.</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<h2 class="text-center align-center justify-center text-3xl">
|
||||
Coming soon...
|
||||
</h2>
|
||||
<div class="flex flex-row flex-wrap justify-center gap-x-10 gap-y-3">
|
||||
<div
|
||||
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5"
|
||||
>
|
||||
<h2 class="text-xl font-bold">Threads 文比較</h2>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5"
|
||||
>
|
||||
<h2 class="text-xl font-bold">新聞 Facebook 觀點</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -36,18 +36,15 @@ soup = BeautifulSoup(html, "html.parser")
|
|||
# Find the topiccwiz element
|
||||
topiccwiz = soup.find_all("c-wiz", class_=topiccwiz_css)
|
||||
news_data = []
|
||||
index = 0
|
||||
for item in topiccwiz:
|
||||
index+= 1
|
||||
array = []
|
||||
hotarticles = item.find_all("article")
|
||||
first_article = ""
|
||||
passed_first = False
|
||||
for article in hotarticles:
|
||||
try:
|
||||
if not passed_first:
|
||||
first_title_elem = article.find('a', class_='gPFEn')
|
||||
first_title = first_title_elem.text.strip() if first_title_elem else ''
|
||||
first_article = first_title
|
||||
passed_first = True
|
||||
continue
|
||||
title_elem = article.find('a', class_='gPFEn')
|
||||
title = title_elem.text.strip() if title_elem else ''
|
||||
|
||||
|
@ -60,13 +57,17 @@ for item in topiccwiz:
|
|||
'title': title,
|
||||
'source': source,
|
||||
'link': link,
|
||||
'category': first_article
|
||||
}
|
||||
news_data.append(article_data)
|
||||
array.append(article_data)
|
||||
except Exception as e:
|
||||
print(f"Error processing article: {e}")
|
||||
continue
|
||||
|
||||
sendData = {
|
||||
index: array
|
||||
}
|
||||
news_data.append(sendData)
|
||||
|
||||
with open('news.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(news_data, f, ensure_ascii=False, indent=2)
|
||||
|
||||
|
|
1026
scraping/news.json
1026
scraping/news.json
File diff suppressed because it is too large
Load diff
|
@ -1,5 +0,0 @@
|
|||
export default defineEventHandler(async (event) => {});
|
||||
|
||||
async function findUser(githubUser: any) {
|
||||
console.log("Github User: " + githubUser);
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import crypto from "node:crypto";
|
||||
export default defineEventHandler(async (event) => {
|
||||
const baseUrl = event.node.req.headers.host;
|
||||
const protocol = process.env.NODE_ENV === "production" ? "https" : "http";
|
||||
const clientId = process.env.NUXT_GITHUB_CLIENT_ID;
|
||||
const callbackUrl = `${protocol}://${baseUrl}/api/auth/github/callback`;
|
||||
const state = crypto.randomBytes(16).toString("hex");
|
||||
setCookie(event, "oauth_state", state, {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
maxAge: 60 * 10,
|
||||
path: "/",
|
||||
});
|
||||
const authorizationUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(callbackUrl)}&scope=read:user,user:email&state=${state}`;
|
||||
await sendRedirect(event, authorizationUrl, 302);
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue