Next.js + Tailwind CSS + TypeScript Starter
-- A starter for Next.js, Tailwind CSS, and TypeScript with Absolute - Import, Seo, Link component, pre-configured with Husky{' '} -
-
-
diff --git a/.npmrc b/.npmrc index b7425b9..e69de29 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +0,0 @@ -enable-pre-post-scripts=true \ No newline at end of file diff --git a/next.config.js b/next.config.js index cbe9676..90a8531 100644 --- a/next.config.js +++ b/next.config.js @@ -8,14 +8,14 @@ const nextConfig = { swcMinify: true, // Uncoment to add domain whitelist - // images: { - // remotePatterns: [ - // { - // protocol: 'https', - // hostname: 'res.cloudinary.com', - // }, - // ] - // }, + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: 'vip.dytt-img.com', + }, + ], + }, webpack(config) { // Grab the existing rule that handles SVG imports diff --git a/package.json b/package.json index 3484756..ad5c56e 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,16 @@ "prepare": "husky install" }, "dependencies": { + "@headlessui/react": "^2.2.4", + "@heroicons/react": "^2.2.0", "clsx": "^2.0.0", + "framer-motion": "^12.18.1", "lucide-react": "^0.438.0", "next": "^14.2.23", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^5.4.0", + "swiper": "^11.2.8", "tailwind-merge": "^2.6.0", "zod": "^3.24.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 86b51c4..7a5341e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,18 @@ importers: .: dependencies: + '@headlessui/react': + specifier: ^2.2.4 + version: 2.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@heroicons/react': + specifier: ^2.2.0 + version: 2.2.0(react@18.3.1) clsx: specifier: ^2.0.0 version: 2.1.1 + framer-motion: + specifier: ^12.18.1 + version: 12.18.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lucide-react: specifier: ^0.438.0 version: 0.438.0(react@18.3.1) @@ -26,6 +35,9 @@ importers: react-icons: specifier: ^5.4.0 version: 5.5.0(react@18.3.1) + swiper: + specifier: ^11.2.8 + version: 11.2.8 tailwind-merge: specifier: ^2.6.0 version: 2.6.0 @@ -849,6 +861,39 @@ packages: resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@floating-ui/core@1.7.1': + resolution: {integrity: sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==} + + '@floating-ui/dom@1.7.1': + resolution: {integrity: sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==} + + '@floating-ui/react-dom@2.1.3': + resolution: {integrity: sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/react@0.26.28': + resolution: {integrity: sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + + '@headlessui/react@2.2.4': + resolution: {integrity: sha512-lz+OGcAH1dK93rgSMzXmm1qKOJkBUqZf1L4M8TWLNplftQD3IkoEDdUFNfAn4ylsN6WOTVtWaLmvmaHOUk1dTA==} + engines: {node: '>=10'} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + + '@heroicons/react@2.2.0': + resolution: {integrity: sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==} + peerDependencies: + react: '>= 16 || ^19.0.0-rc' + '@humanwhocodes/config-array@0.13.0': resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} @@ -1056,6 +1101,43 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@react-aria/focus@3.20.5': + resolution: {integrity: sha512-JpFtXmWQ0Oca7FcvkqgjSyo6xEP7v3oQOLUId6o0xTvm4AD5W0mU2r3lYrbhsJ+XxdUUX4AVR5473sZZ85kU4A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/interactions@3.25.3': + resolution: {integrity: sha512-J1bhlrNtjPS/fe5uJQ+0c7/jiXniwa4RQlP+Emjfc/iuqpW2RhbF9ou5vROcLzWIyaW8tVMZ468J68rAs/aZ5A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/ssr@3.9.9': + resolution: {integrity: sha512-2P5thfjfPy/np18e5wD4WPt8ydNXhij1jwA8oehxZTFqlgVMGXzcWKxTb4RtJrLFsqPO7RUQTiY8QJk0M4Vy2g==} + engines: {node: '>= 12'} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/utils@3.29.1': + resolution: {integrity: sha512-yXMFVJ73rbQ/yYE/49n5Uidjw7kh192WNN9PNQGV0Xoc7EJUlSOxqhnpHmYTyO0EotJ8fdM1fMH8durHjUSI8g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-stately/flags@3.1.2': + resolution: {integrity: sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==} + + '@react-stately/utils@3.10.7': + resolution: {integrity: sha512-cWvjGAocvy4abO9zbr6PW6taHgF24Mwy/LbQ4TC4Aq3tKdKDntxyD+sh7AkSRfJRT2ccMVaHVv2+FfHThd3PKQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/shared@3.30.0': + resolution: {integrity: sha512-COIazDAx1ncDg046cTJ8SFYsX8aS3lB/08LDnbkH/SkdYrFPWDlXMrO/sUam8j1WWM+PJ+4d1mj7tODIKNiFog==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -1160,6 +1242,15 @@ packages: peerDependencies: tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1' + '@tanstack/react-virtual@3.13.10': + resolution: {integrity: sha512-nvrzk4E9mWB4124YdJ7/yzwou7IfHxlSef6ugCFcBfRmsnsma3heciiiV97sBNxyc3VuwtZvmwXd0aB5BpucVw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/virtual-core@3.13.10': + resolution: {integrity: sha512-sPEDhXREou5HyZYqSWIqdU580rsF6FGeN7vpzijmP3KTiOGjOMZASz4Y6+QKjiFQwhWrR58OP8izYaNGVxvViA==} + '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} @@ -2346,6 +2437,20 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + framer-motion@12.18.1: + resolution: {integrity: sha512-6o4EDuRPLk4LSZ1kRnnEOurbQ86MklVk+Y1rFBUKiF+d2pCdvMjWVu0ZkyMVCTwl5UyTH2n/zJEJx+jvTYuxow==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} @@ -3148,6 +3253,12 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + motion-dom@12.18.1: + resolution: {integrity: sha512-dR/4EYT23Snd+eUSLrde63Ws3oXQtJNw/krgautvTfwrN/2cHfCZMdu6CeTxVfRRWREW3Fy1f5vobRDiBb/q+w==} + + motion-utils@12.18.1: + resolution: {integrity: sha512-az26YDU4WoDP0ueAkUtABLk2BIxe28d8NH1qWT8jPGhPyf44XTdDUh8pDk9OPphaSrR9McgpcJlgwSOIw/sfkA==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3930,9 +4041,16 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + swiper@11.2.8: + resolution: {integrity: sha512-S5FVf6zWynPWooi7pJ7lZhSUe2snTzqLuUzbd5h5PHUOhzgvW0bLKBd2wv0ixn6/5o9vwc/IkQT74CRcLJQzeg==} + engines: {node: '>= 4.7.0'} + symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + tailwind-merge@2.6.0: resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} @@ -4125,6 +4243,11 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + use-sync-external-store@1.5.0: + resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -5224,6 +5347,45 @@ snapshots: '@eslint/js@8.57.1': {} + '@floating-ui/core@1.7.1': + dependencies: + '@floating-ui/utils': 0.2.9 + + '@floating-ui/dom@1.7.1': + dependencies: + '@floating-ui/core': 1.7.1 + '@floating-ui/utils': 0.2.9 + + '@floating-ui/react-dom@2.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.7.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@floating-ui/react@0.26.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/utils': 0.2.9 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tabbable: 6.2.0 + + '@floating-ui/utils@0.2.9': {} + + '@headlessui/react@2.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react': 0.26.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@react-aria/focus': 3.20.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@react-aria/interactions': 3.25.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tanstack/react-virtual': 3.13.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + use-sync-external-store: 1.5.0(react@18.3.1) + + '@heroicons/react@2.2.0(react@18.3.1)': + dependencies: + react: 18.3.1 + '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -5509,6 +5671,55 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@react-aria/focus@3.20.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@react-aria/interactions': 3.25.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@react-aria/utils': 3.29.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@react-types/shared': 3.30.0(react@18.3.1) + '@swc/helpers': 0.5.5 + clsx: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@react-aria/interactions@3.25.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@react-aria/ssr': 3.9.9(react@18.3.1) + '@react-aria/utils': 3.29.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@react-stately/flags': 3.1.2 + '@react-types/shared': 3.30.0(react@18.3.1) + '@swc/helpers': 0.5.5 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@react-aria/ssr@3.9.9(react@18.3.1)': + dependencies: + '@swc/helpers': 0.5.5 + react: 18.3.1 + + '@react-aria/utils@3.29.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@react-aria/ssr': 3.9.9(react@18.3.1) + '@react-stately/flags': 3.1.2 + '@react-stately/utils': 3.10.7(react@18.3.1) + '@react-types/shared': 3.30.0(react@18.3.1) + '@swc/helpers': 0.5.5 + clsx: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@react-stately/flags@3.1.2': + dependencies: + '@swc/helpers': 0.5.5 + + '@react-stately/utils@3.10.7(react@18.3.1)': + dependencies: + '@swc/helpers': 0.5.5 + react: 18.3.1 + + '@react-types/shared@3.30.0(react@18.3.1)': + dependencies: + react: 18.3.1 + '@rtsao/scc@1.1.0': {} '@rushstack/eslint-patch@1.11.0': {} @@ -5628,6 +5839,14 @@ snapshots: mini-svg-data-uri: 1.4.4 tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@24.0.3)(typescript@4.9.5)) + '@tanstack/react-virtual@3.13.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/virtual-core': 3.13.10 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@tanstack/virtual-core@3.13.10': {} + '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.27.1 @@ -7018,6 +7237,15 @@ snapshots: fraction.js@4.3.7: {} + framer-motion@12.18.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + motion-dom: 12.18.1 + motion-utils: 12.18.1 + tslib: 2.8.1 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 @@ -8092,6 +8320,12 @@ snapshots: minipass@7.1.2: {} + motion-dom@12.18.1: + dependencies: + motion-utils: 12.18.1 + + motion-utils@12.18.1: {} + ms@2.1.3: {} mz@2.7.0: @@ -8863,8 +9097,12 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 + swiper@11.2.8: {} + symbol-tree@3.2.4: {} + tabbable@6.2.0: {} + tailwind-merge@2.6.0: {} tailwindcss@3.4.17(ts-node@10.9.2(@types/node@24.0.3)(typescript@4.9.5)): @@ -9103,6 +9341,10 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 + use-sync-external-store@1.5.0(react@18.3.1): + dependencies: + react: 18.3.1 + util-deprecate@1.0.2: {} v8-compile-cache-lib@3.0.1: {} diff --git a/src/app/components/page.tsx b/src/app/components/page.tsx index 947aea9..74e8bd8 100644 --- a/src/app/components/page.tsx +++ b/src/app/components/page.tsx @@ -9,7 +9,7 @@ import { Plus, Shield, } from 'lucide-react'; -import React from 'react'; +import * as React from 'react'; import Button from '@/components/buttons/Button'; import IconButton from '@/components/buttons/IconButton'; diff --git a/src/app/globals.css b/src/app/globals.css new file mode 100644 index 0000000..bf6a451 --- /dev/null +++ b/src/app/globals.css @@ -0,0 +1,59 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --foreground-rgb: 255, 255, 255; +} + +body { + color: rgb(var(--foreground-rgb)); + background: linear-gradient( + 180deg, + #e6f3fb 0%, + #eaf3f7 18%, + #f7f7f3 38%, + #e9ecef 60%, + #dbe3ea 80%, + #d3dde6 100% + ); + background-attachment: fixed; + min-height: 100vh; +} + +/* 自定义滚动条样式 */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: rgba(31, 41, 55, 0.1); +} + +::-webkit-scrollbar-thumb { + background: rgba(75, 85, 99, 0.3); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(107, 114, 128, 0.5); +} + +/* 视频卡片悬停效果 */ +.video-card-hover { + transition: transform 0.3s ease; +} + +.video-card-hover:hover { + transform: scale(1.05); +} + +/* 渐变遮罩 */ +.gradient-overlay { + background: linear-gradient( + to bottom, + rgba(0, 0, 0, 0) 0%, + rgba(0, 0, 0, 0.8) 100% + ); +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f1184cf..d7afc12 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,52 +1,13 @@ -import { Metadata } from 'next'; -import * as React from 'react'; +import type { Metadata } from 'next'; +import { Inter } from 'next/font/google'; -import '@/styles/globals.css'; -// !STARTERCONF This is for demo purposes, remove @/styles/colors.css import immediately -import '@/styles/colors.css'; +import './globals.css'; -import { siteConfig } from '@/constant/config'; +const inter = Inter({ subsets: ['latin'] }); -// !STARTERCONF Change these default meta -// !STARTERCONF Look at @/constant/config to change them export const metadata: Metadata = { - metadataBase: new URL(siteConfig.url), - title: { - default: siteConfig.title, - template: `%s | ${siteConfig.title}`, - }, - description: siteConfig.description, - robots: { index: true, follow: true }, - // !STARTERCONF this is the default favicon, you can generate your own from https://realfavicongenerator.net/ - // ! copy to /favicon folder - icons: { - icon: '/favicon/favicon.ico', - shortcut: '/favicon/favicon-16x16.png', - apple: '/favicon/apple-touch-icon.png', - }, - manifest: `/favicon/site.webmanifest`, - openGraph: { - url: siteConfig.url, - title: siteConfig.title, - description: siteConfig.description, - siteName: siteConfig.title, - images: [`${siteConfig.url}/images/og.jpg`], - type: 'website', - locale: 'en_US', - }, - twitter: { - card: 'summary_large_image', - title: siteConfig.title, - description: siteConfig.description, - images: [`${siteConfig.url}/images/og.jpg`], - // creator: '@th_clarence', - }, - // authors: [ - // { - // name: 'Theodorus Clarence', - // url: 'https://theodorusclarence.com', - // }, - // ], + title: '聚合视频站', + description: '一个聚合多个视频源的现代化视频网站', }; export default function RootLayout({ @@ -55,8 +16,10 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( - -
{children} + + + {children} + ); } diff --git a/src/app/page.tsx b/src/app/page.tsx index cf0ed16..8a8f41d 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,72 +1,130 @@ 'use client'; -import Head from 'next/head'; -import * as React from 'react'; -import '@/lib/env'; +import { useState } from 'react'; -import ArrowLink from '@/components/links/ArrowLink'; -import ButtonLink from '@/components/links/ButtonLink'; -import UnderlineLink from '@/components/links/UnderlineLink'; -import UnstyledLink from '@/components/links/UnstyledLink'; +import CapsuleSwitch from '@/components/CapsuleSwitch'; +import Sidebar from '@/components/layout/Sidebar'; +import SearchCard from '@/components/video/SearchCard'; +import VideoCard from '@/components/video/VideoCard'; -/** - * SVGR Support - * Caveat: No React Props Type. - * - * You can override the next-env if the type is important to you - * @see https://stackoverflow.com/questions/68103844/how-to-override-next-js-svg-module-declaration - */ -import Logo from '~/svg/Logo.svg'; +const defaultPoster = + 'https://vip.dytt-img.com/upload/vod/20250326-1/9857e2e8581f231e24747ee32e633a3b.jpg'; -// !STARTERCONF -> Select !STARTERCONF and CMD + SHIFT + F -// Before you begin editing, follow all comments with `STARTERCONF`, -// to customize the default configuration. +// 模拟数据 +const mockData = { + recentMovies: [ + { + id: 1, + title: '流浪地球2', + poster: defaultPoster, + rating: 8.3, + type: 'movie' as const, + source: '电影天堂', + }, + { + id: 2, + title: '满江红', + poster: defaultPoster, + rating: 7.5, + type: 'movie' as const, + source: '电影天堂', + }, + ], + recentTvShows: [ + { + id: 3, + title: '三体', + poster: defaultPoster, + rating: 8.7, + type: 'tv' as const, + episodes: 30, + source: '电影天堂', + }, + { + id: 4, + title: '狂飙', + poster: defaultPoster, + rating: 8.5, + type: 'tv' as const, + episodes: 39, + source: '电影天堂', + }, + ], +}; + +export default function Home() { + const [sidebarCollapsed, setSidebarCollapsed] = useState(false); + const [activeTab, setActiveTab] = useState('home'); // 'home' 或 'favorites' -export default function HomePage() { return ( -- A starter for Next.js, Tailwind CSS, and TypeScript with Absolute - Import, Seo, Link component, pre-configured with Husky{' '} -
-
-