From 8d3c805985edbba97a41a029001dc01a5ebf27f1 Mon Sep 17 00:00:00 2001 From: eeymoo Date: Thu, 20 Mar 2025 05:47:13 +0000 Subject: [PATCH] wip: change local dev --- app/api/auth/[...nextauth]/route.ts | 2 + app/globals.css | 26 +---- app/page.tsx | 112 +++---------------- app/settings/page.tsx | 0 app/signin/page.tsx | 42 ++++++++ auth.ts | 20 ++++ components/DraggablePanel.tsx | 32 ++++++ components/DraggableWidget.tsx | 109 +++++++++++++++++++ components/Logo.tsx | 9 ++ middleware.ts | 1 + package.json | 17 +-- pnpm-lock.yaml | 160 +++++++++++++++++++++++++++- types/plugin.d.ts | 7 ++ 13 files changed, 407 insertions(+), 130 deletions(-) create mode 100644 app/api/auth/[...nextauth]/route.ts create mode 100644 app/settings/page.tsx create mode 100644 app/signin/page.tsx create mode 100644 auth.ts create mode 100644 components/DraggablePanel.tsx create mode 100644 components/DraggableWidget.tsx create mode 100644 components/Logo.tsx create mode 100644 middleware.ts create mode 100644 types/plugin.d.ts diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 0000000..0eebb94 --- /dev/null +++ b/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,2 @@ +import { handlers } from "@/auth" +export const { GET, POST } = handlers \ No newline at end of file diff --git a/app/globals.css b/app/globals.css index a2dc41e..74d8662 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,26 +1,2 @@ @import "tailwindcss"; - -:root { - --background: #ffffff; - --foreground: #171717; -} - -@theme inline { - --color-background: var(--background); - --color-foreground: var(--foreground); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - -body { - background: var(--background); - color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; -} +@plugin "daisyui"; \ No newline at end of file diff --git a/app/page.tsx b/app/page.tsx index 88f0cc9..fd1afc8 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,103 +1,21 @@ -import Image from "next/image"; +import DraggablePanel from "@/components/DraggablePanel"; +import DraggableWidget from "@/components/DraggableWidget"; +import Logo from "@/components/Logo"; export default function Home() { return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{" "} - - app/page.tsx - - . -
  2. -
  3. - Save and see your changes instantly. -
  4. -
- -
- - Vercel logomark - Deploy now - - - Read our docs - -
-
- +
+ + + + + + + + + + +
); } diff --git a/app/settings/page.tsx b/app/settings/page.tsx new file mode 100644 index 0000000..e69de29 diff --git a/app/signin/page.tsx b/app/signin/page.tsx new file mode 100644 index 0000000..0812706 --- /dev/null +++ b/app/signin/page.tsx @@ -0,0 +1,42 @@ +import "@/app/globals.css"; +import Logo from "@/components/Logo"; + +export default function LoginPage() { + return ( +
+
+ {/* Logo Section */} +
+ +

+ 登录您的账户 +

+
+ + {/* Login Form */} +
+ {/* Email Input */} +
+ +
+ + {/* Password Input */} +
+ +
+ + {/* Remember Me & Forgot Password */} +
+ +
+ + {/* Submit Button */} + +
+
+
+ ) +} diff --git a/auth.ts b/auth.ts new file mode 100644 index 0000000..cb85747 --- /dev/null +++ b/auth.ts @@ -0,0 +1,20 @@ +import NextAuth, { CredentialsSignin } from "next-auth" +import Credentials from "next-auth/providers/credentials" + +class InvalidLoginError extends CredentialsSignin { + code = "Invalid identifier or password" +} + +export const { handlers, signIn, signOut, auth } = NextAuth({ + providers: [ + Credentials({ + credentials: { + username: { label: "Username" }, + password: { label: "Password", type: "password" }, + }, + async authorize(credentials) { + throw new InvalidLoginError() + }, + }), + ], +}) \ No newline at end of file diff --git a/components/DraggablePanel.tsx b/components/DraggablePanel.tsx new file mode 100644 index 0000000..89b0429 --- /dev/null +++ b/components/DraggablePanel.tsx @@ -0,0 +1,32 @@ +"use client"; +import { ReactElement } from 'react'; +import classnames from 'classnames'; + +export default function DraggablePanel(props: DraggablePanelType) { + const { draggable, wdith = 'full', height = 'full', children } = props; + + const draggablePanelClass = classnames( + 'p-8 grid gap-[16px]', + `h-${height} w-${wdith}`, + { + 'h-full': height === 'full' || height === '100%', + 'w-full': wdith === 'full' || wdith === '100%', + 'base-200': draggable, // 当 active 为 true 时添加 + 'base-100': !draggable, // 当 disabled 为 true 时添加 + }); + return ( +
+ { + children + } +
+ ); +} + +export type DraggablePanelType = { + draggable: boolean; + wdith?: number | string; + height?: number | string; + children: any; + // grid: boolean; +} diff --git a/components/DraggableWidget.tsx b/components/DraggableWidget.tsx new file mode 100644 index 0000000..7e7182e --- /dev/null +++ b/components/DraggableWidget.tsx @@ -0,0 +1,109 @@ +"use client"; +import { CSSProperties, ReactElement, useEffect, useRef, useState } from "react"; +import classnames from 'classnames'; +import _ from 'lodash'; + + +export default function DraggableWidget(props: DraggableWidgetType) { + const { children, x, y, w, h } = props; + const targetRef = useRef(null); + const containerRef = useRef(null); + + const [size, setSize] = useState({ width: 16, height: 16 }); + const [isResize, setIsResize] = useState(false); + + useEffect(() => { + const element = targetRef.current; + if (!element) return; + + // 创建 ResizeObserver 实例 + let timer:any; + const observer = new ResizeObserver(_.throttle((entries: any) => { + for (const entry of entries) { + const { width, height } = entry.contentRect; + setSize({ + width: nearestMultipleOf16(width), + height: nearestMultipleOf16(height) + }); + if (timer) { + clearTimeout(timer); + } + setIsResize(true); + timer = setTimeout(() => { + entry.target.style.width = nearestMultipleOf16(width) + 'px'; + entry.target.style.height = nearestMultipleOf16(height) + 'px'; + // syncSize(entry.contentRect, containerRef.current); + setIsResize(false); + }, 150) + } + }, 30)); + + + const syncSize = (contentRect, containerNode) => { + const { x, y, height, width } = contentRect; + const area = { + rowStart: x/16 + 1, + columnStart: y/16 + 1, + rowEnd: width/16+x/16 + 1, + columnEnd: height/16+y/16 + 1 + } + containerNode.style.gridArea = `${area.rowStart} / ${area.columnStart} / ${area.rowEnd} / ${area.columnEnd}`; + } + + // 开始观察元素 + observer.observe(element); + + // 组件卸载时断开连接 + return () => { + observer.disconnect(); + }; + }, []); // 空依赖数组确保只运行一次 + + + const draggableWidgetClass = classnames( + 'hover:bg-red-200 hover:outline-2 hover:outline-dashed hover:outline-gray-300 hover:opacity-30 resize block rounded-lg w-64 h-64 max-h-[1048px] max-w-[1888px] cursor-pointer overflow-hidden ', { + } + ); + + const draggableWidgetIndicatorBoxClass = classnames( + 'absolute top-0 left-0 outline-2 outline-dashed outline-red-500 z-50 pointer-events-none', + { + 'invisible': !isResize + } + ); + + return ( +
+
+ { + children + } +
+
{`${size.width}x${size.height}`}
+
+ ); +} + +export type DraggableWidgetType = { + draggable: boolean; + wdith?: number | string; + height?: number | string; + children: ReactElement; + x: number; + y: number; + w: number; + h: number; +} + +/** + * 计算最接近的 16 的倍数 + * @param n 输入的数字 + * @returns 最近的 16 的倍数 + */ +function nearestMultipleOf16(n: number): number { + return Math.floor((n + 8) / 16) * 16; +} \ No newline at end of file diff --git a/components/Logo.tsx b/components/Logo.tsx new file mode 100644 index 0000000..0db090b --- /dev/null +++ b/components/Logo.tsx @@ -0,0 +1,9 @@ +import "@/app/globals.css"; +export default function Home() { + return ( +
+ NEXUSHUB +
+ ); + } + \ No newline at end of file diff --git a/middleware.ts b/middleware.ts new file mode 100644 index 0000000..2df914b --- /dev/null +++ b/middleware.ts @@ -0,0 +1 @@ +export { auth as middleware } from "@/auth" \ No newline at end of file diff --git a/package.json b/package.json index 1fe5504..cf978e4 100644 --- a/package.json +++ b/package.json @@ -9,19 +9,24 @@ "lint": "next lint" }, "dependencies": { + "@dnd-kit/core": "^6.3.1", + "classnames": "^2.5.1", + "lodash": "^4.17.21", + "next": "15.2.3", + "next-auth": "5.0.0-beta.25", "react": "^19.0.0", - "react-dom": "^19.0.0", - "next": "15.2.3" + "react-dom": "^19.0.0" }, "devDependencies": { - "typescript": "^5", + "@eslint/eslintrc": "^3", + "@tailwindcss/postcss": "^4.0.14", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", - "@tailwindcss/postcss": "^4", - "tailwindcss": "^4", + "daisyui": "^5.0.6", "eslint": "^9", "eslint-config-next": "15.2.3", - "@eslint/eslintrc": "^3" + "tailwindcss": "^4.0.14", + "typescript": "^5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dc615fb..1655709 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,21 @@ importers: .: dependencies: + '@dnd-kit/core': + specifier: ^6.3.1 + version: 6.3.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + classnames: + specifier: ^2.5.1 + version: 2.5.1 + lodash: + specifier: ^4.17.21 + version: 4.17.21 next: specifier: 15.2.3 version: 15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + next-auth: + specifier: 5.0.0-beta.25 + version: 5.0.0-beta.25(next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0) react: specifier: ^19.0.0 version: 19.0.0 @@ -22,7 +34,7 @@ importers: specifier: ^3 version: 3.3.0 '@tailwindcss/postcss': - specifier: ^4 + specifier: ^4.0.14 version: 4.0.14 '@types/node': specifier: ^20 @@ -33,6 +45,9 @@ importers: '@types/react-dom': specifier: ^19 version: 19.0.4(@types/react@19.0.11) + daisyui: + specifier: ^5.0.6 + version: 5.0.6 eslint: specifier: ^9 version: 9.22.0(jiti@2.4.2) @@ -40,7 +55,7 @@ importers: specifier: 15.2.3 version: 15.2.3(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) tailwindcss: - specifier: ^4 + specifier: ^4.0.14 version: 4.0.14 typescript: specifier: ^5 @@ -52,6 +67,36 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@auth/core@0.37.2': + resolution: {integrity: sha512-kUvzyvkcd6h1vpeMAojK2y7+PAV5H+0Cc9+ZlKYDFhDY31AlvsB+GW5vNO4qE3Y07KeQgvNO9U0QUx/fN62kBw==} + peerDependencies: + '@simplewebauthn/browser': ^9.0.1 + '@simplewebauthn/server': ^9.0.2 + nodemailer: ^6.8.0 + peerDependenciesMeta: + '@simplewebauthn/browser': + optional: true + '@simplewebauthn/server': + optional: true + nodemailer: + optional: true + + '@dnd-kit/accessibility@3.1.1': + resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==} + peerDependencies: + react: '>=16.8.0' + + '@dnd-kit/core@6.3.1': + resolution: {integrity: sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@dnd-kit/utilities@3.2.2': + resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==} + peerDependencies: + react: '>=16.8.0' + '@emnapi/core@1.3.1': resolution: {integrity: sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==} @@ -297,6 +342,9 @@ packages: resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} engines: {node: '>=12.4.0'} + '@panva/hkdf@1.2.1': + resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==} + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -388,6 +436,9 @@ packages: '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} @@ -625,6 +676,9 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} @@ -645,6 +699,10 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -652,6 +710,9 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + daisyui@5.0.6: + resolution: {integrity: sha512-/e/9Gw/2y9oawBJlWkJMSEhRXdmfOLvcPl+6q/x2rPEdIVOtebs1t3ex2vwySl9vCRs1GGNBKCiL+P60Ps/wUw==} + damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} @@ -1127,6 +1188,9 @@ packages: resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} hasBin: true + jose@5.10.0: + resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1236,6 +1300,9 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -1273,6 +1340,22 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + next-auth@5.0.0-beta.25: + resolution: {integrity: sha512-2dJJw1sHQl2qxCrRk+KTQbeH+izFbGFPuJj5eGgBZFYyiYYtvlrBeUw1E/OJJxTRjuxbSYGnCTkUIRsIIW0bog==} + peerDependencies: + '@simplewebauthn/browser': ^9.0.1 + '@simplewebauthn/server': ^9.0.2 + next: ^14.0.0-0 || ^15.0.0-0 + nodemailer: ^6.6.5 + react: ^18.2.0 || ^19.0.0-0 + peerDependenciesMeta: + '@simplewebauthn/browser': + optional: true + '@simplewebauthn/server': + optional: true + nodemailer: + optional: true + next@15.2.3: resolution: {integrity: sha512-x6eDkZxk2rPpu46E1ZVUWIBhYCLszmUY6fvHBFcbzJ9dD+qRX6vcHusaqqDlnY+VngKzKbAiG2iRCkPbmi8f7w==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} @@ -1294,6 +1377,9 @@ packages: sass: optional: true + oauth4webapi@3.3.1: + resolution: {integrity: sha512-ZwX7UqYrP3Lr+Glhca3a1/nF2jqf7VVyJfhGuW5JtrfDUxt0u+IoBPzFjZ2dd7PJGkdM6CFPVVYzuDYKHv101A==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -1380,10 +1466,21 @@ packages: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} + preact-render-to-string@5.2.3: + resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==} + peerDependencies: + preact: '>=10' + + preact@10.11.3: + resolution: {integrity: sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + pretty-format@3.8.0: + resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -1665,6 +1762,34 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@auth/core@0.37.2': + dependencies: + '@panva/hkdf': 1.2.1 + '@types/cookie': 0.6.0 + cookie: 0.7.1 + jose: 5.10.0 + oauth4webapi: 3.3.1 + preact: 10.11.3 + preact-render-to-string: 5.2.3(preact@10.11.3) + + '@dnd-kit/accessibility@3.1.1(react@19.0.0)': + dependencies: + react: 19.0.0 + tslib: 2.8.1 + + '@dnd-kit/core@6.3.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@dnd-kit/accessibility': 3.1.1(react@19.0.0) + '@dnd-kit/utilities': 3.2.2(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + tslib: 2.8.1 + + '@dnd-kit/utilities@3.2.2(react@19.0.0)': + dependencies: + react: 19.0.0 + tslib: 2.8.1 + '@emnapi/core@1.3.1': dependencies: '@emnapi/wasi-threads': 1.0.1 @@ -1864,6 +1989,8 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} + '@panva/hkdf@1.2.1': {} + '@rtsao/scc@1.1.0': {} '@rushstack/eslint-patch@1.11.0': {} @@ -1941,6 +2068,8 @@ snapshots: tslib: 2.8.1 optional: true + '@types/cookie@0.6.0': {} + '@types/estree@1.0.6': {} '@types/json-schema@7.0.15': {} @@ -2214,6 +2343,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + classnames@2.5.1: {} + client-only@0.0.1: {} color-convert@2.0.1: @@ -2236,6 +2367,8 @@ snapshots: concat-map@0.0.1: {} + cookie@0.7.1: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -2244,6 +2377,8 @@ snapshots: csstype@3.1.3: {} + daisyui@5.0.6: {} + damerau-levenshtein@1.0.8: {} data-view-buffer@1.0.2: @@ -2882,6 +3017,8 @@ snapshots: jiti@2.4.2: {} + jose@5.10.0: {} + js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -2971,6 +3108,8 @@ snapshots: lodash.merge@4.6.2: {} + lodash@4.17.21: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -3000,6 +3139,12 @@ snapshots: natural-compare@1.4.0: {} + next-auth@5.0.0-beta.25(next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0): + dependencies: + '@auth/core': 0.37.2 + next: 15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + react: 19.0.0 + next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: '@next/env': 15.2.3 @@ -3025,6 +3170,8 @@ snapshots: - '@babel/core' - babel-plugin-macros + oauth4webapi@3.3.1: {} + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -3120,8 +3267,17 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + preact-render-to-string@5.2.3(preact@10.11.3): + dependencies: + preact: 10.11.3 + pretty-format: 3.8.0 + + preact@10.11.3: {} + prelude-ls@1.2.1: {} + pretty-format@3.8.0: {} + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 diff --git a/types/plugin.d.ts b/types/plugin.d.ts new file mode 100644 index 0000000..4f47024 --- /dev/null +++ b/types/plugin.d.ts @@ -0,0 +1,7 @@ +export interface CardPlugin { + id: string; // 唯一标识 + displayName: string; // 显示名称 + component: React.ComponentType<{ config?: any }>; // 卡片组件 + configSchema?: any; // 配置的JSON Schema(用于后台配置界面) + +}