mirror of
https://github.com/hamster1963/nezha-dash.git
synced 2025-04-24 21:10:45 +08:00
Compare commits
5 Commits
68b7034db6
...
cc97147270
Author | SHA1 | Date | |
---|---|---|---|
|
cc97147270 | ||
|
6bc7e0de0e | ||
|
6ba7747dd6 | ||
|
15086d054a | ||
|
6979139c98 |
@ -1,6 +1,10 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { ServerDataWithTimestamp, useServerData } from "@/app/lib/server-data-context"
|
import {
|
||||||
|
MAX_HISTORY_LENGTH,
|
||||||
|
ServerDataWithTimestamp,
|
||||||
|
useServerData,
|
||||||
|
} from "@/app/lib/server-data-context"
|
||||||
import { NezhaAPISafe } from "@/app/types/nezha-api"
|
import { NezhaAPISafe } from "@/app/types/nezha-api"
|
||||||
import { ServerDetailChartLoading } from "@/components/loading/ServerDetailLoading"
|
import { ServerDetailChartLoading } from "@/components/loading/ServerDetailLoading"
|
||||||
import AnimatedCircularProgressBar from "@/components/ui/animated-circular-progress-bar"
|
import AnimatedCircularProgressBar from "@/components/ui/animated-circular-progress-bar"
|
||||||
@ -122,7 +126,7 @@ function CpuChart({ history, data }: { history: ServerDataWithTimestamp[]; data:
|
|||||||
} else {
|
} else {
|
||||||
newData = [...cpuChartData, { timeStamp: timestamp, cpu: cpu }]
|
newData = [...cpuChartData, { timeStamp: timestamp, cpu: cpu }]
|
||||||
}
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > MAX_HISTORY_LENGTH) {
|
||||||
newData.shift()
|
newData.shift()
|
||||||
}
|
}
|
||||||
setCpuChartData(newData)
|
setCpuChartData(newData)
|
||||||
@ -245,7 +249,7 @@ function ProcessChart({
|
|||||||
} else {
|
} else {
|
||||||
newData = [...processChartData, { timeStamp: timestamp, process: process }]
|
newData = [...processChartData, { timeStamp: timestamp, process: process }]
|
||||||
}
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > MAX_HISTORY_LENGTH) {
|
||||||
newData.shift()
|
newData.shift()
|
||||||
}
|
}
|
||||||
setProcessChartData(newData)
|
setProcessChartData(newData)
|
||||||
@ -349,7 +353,7 @@ function MemChart({ data, history }: { data: NezhaAPISafe; history: ServerDataWi
|
|||||||
} else {
|
} else {
|
||||||
newData = [...memChartData, { timeStamp: timestamp, mem: mem, swap: swap }]
|
newData = [...memChartData, { timeStamp: timestamp, mem: mem, swap: swap }]
|
||||||
}
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > MAX_HISTORY_LENGTH) {
|
||||||
newData.shift()
|
newData.shift()
|
||||||
}
|
}
|
||||||
setMemChartData(newData)
|
setMemChartData(newData)
|
||||||
@ -502,7 +506,7 @@ function DiskChart({ data, history }: { data: NezhaAPISafe; history: ServerDataW
|
|||||||
} else {
|
} else {
|
||||||
newData = [...diskChartData, { timeStamp: timestamp, disk: disk }]
|
newData = [...diskChartData, { timeStamp: timestamp, disk: disk }]
|
||||||
}
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > MAX_HISTORY_LENGTH) {
|
||||||
newData.shift()
|
newData.shift()
|
||||||
}
|
}
|
||||||
setDiskChartData(newData)
|
setDiskChartData(newData)
|
||||||
@ -631,7 +635,7 @@ function NetworkChart({
|
|||||||
} else {
|
} else {
|
||||||
newData = [...networkChartData, { timeStamp: timestamp, upload: up, download: down }]
|
newData = [...networkChartData, { timeStamp: timestamp, upload: up, download: down }]
|
||||||
}
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > MAX_HISTORY_LENGTH) {
|
||||||
newData.shift()
|
newData.shift()
|
||||||
}
|
}
|
||||||
setNetworkChartData(newData)
|
setNetworkChartData(newData)
|
||||||
@ -779,7 +783,7 @@ function ConnectChart({
|
|||||||
} else {
|
} else {
|
||||||
newData = [...connectChartData, { timeStamp: timestamp, tcp: tcp, udp: udp }]
|
newData = [...connectChartData, { timeStamp: timestamp, tcp: tcp, udp: udp }]
|
||||||
}
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > MAX_HISTORY_LENGTH) {
|
||||||
newData.shift()
|
newData.shift()
|
||||||
}
|
}
|
||||||
setConnectChartData(newData)
|
setConnectChartData(newData)
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
import { TooltipProvider } from "@/app/(main)/ClientComponents/detail/TooltipContext"
|
||||||
|
import GlobalInfo from "@/app/(main)/ClientComponents/main/GlobalInfo"
|
||||||
|
import { InteractiveMap } from "@/app/(main)/ClientComponents/main/InteractiveMap"
|
||||||
import { useServerData } from "@/app/lib/server-data-context"
|
import { useServerData } from "@/app/lib/server-data-context"
|
||||||
|
import GlobalLoading from "@/components/loading/GlobalLoading"
|
||||||
import GlobalLoading from "../../../../components/loading/GlobalLoading"
|
import { geoJsonString } from "@/lib/geo-json-string"
|
||||||
import { geoJsonString } from "../../../../lib/geo-json-string"
|
|
||||||
import { TooltipProvider } from "../detail/TooltipContext"
|
|
||||||
import GlobalInfo from "./GlobalInfo"
|
|
||||||
import { InteractiveMap } from "./InteractiveMap"
|
|
||||||
|
|
||||||
export default function ServerGlobal() {
|
export default function ServerGlobal() {
|
||||||
const { data: nezhaServerList, error } = useServerData()
|
const { data: nezhaServerList, error } = useServerData()
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
import { useTooltip } from "@/app/(main)/ClientComponents/detail/TooltipContext"
|
||||||
|
import MapTooltip from "@/app/(main)/ClientComponents/main/MapTooltip"
|
||||||
import { countryCoordinates } from "@/lib/geo-limit"
|
import { countryCoordinates } from "@/lib/geo-limit"
|
||||||
import { geoEquirectangular, geoPath } from "d3-geo"
|
import { geoEquirectangular, geoPath } from "d3-geo"
|
||||||
|
|
||||||
import { useTooltip } from "../detail/TooltipContext"
|
|
||||||
import MapTooltip from "./MapTooltip"
|
|
||||||
|
|
||||||
interface InteractiveMapProps {
|
interface InteractiveMapProps {
|
||||||
countries: string[]
|
countries: string[]
|
||||||
serverCounts: { [key: string]: number }
|
serverCounts: { [key: string]: number }
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
import { useTooltip } from "@/app/(main)/ClientComponents/detail/TooltipContext"
|
||||||
import { useTranslations } from "next-intl"
|
import { useTranslations } from "next-intl"
|
||||||
import { memo } from "react"
|
import { memo } from "react"
|
||||||
|
|
||||||
import { useTooltip } from "../detail/TooltipContext"
|
|
||||||
|
|
||||||
const MapTooltip = memo(function MapTooltip() {
|
const MapTooltip = memo(function MapTooltip() {
|
||||||
const { tooltipData } = useTooltip()
|
const { tooltipData } = useTooltip()
|
||||||
const t = useTranslations("Global")
|
const t = useTranslations("Global")
|
||||||
|
@ -4,6 +4,7 @@ import { useServerData } from "@/app/lib/server-data-context"
|
|||||||
import ServerCard from "@/components/ServerCard"
|
import ServerCard from "@/components/ServerCard"
|
||||||
import ServerCardInline from "@/components/ServerCardInline"
|
import ServerCardInline from "@/components/ServerCardInline"
|
||||||
import Switch from "@/components/Switch"
|
import Switch from "@/components/Switch"
|
||||||
|
import GlobalLoading from "@/components/loading/GlobalLoading"
|
||||||
import { Loader } from "@/components/loading/Loader"
|
import { Loader } from "@/components/loading/Loader"
|
||||||
import getEnv from "@/lib/env-entry"
|
import getEnv from "@/lib/env-entry"
|
||||||
import { useFilter } from "@/lib/network-filter-context"
|
import { useFilter } from "@/lib/network-filter-context"
|
||||||
@ -14,8 +15,6 @@ import { useTranslations } from "next-intl"
|
|||||||
import dynamic from "next/dynamic"
|
import dynamic from "next/dynamic"
|
||||||
import { useEffect, useRef, useState } from "react"
|
import { useEffect, useRef, useState } from "react"
|
||||||
|
|
||||||
import GlobalLoading from "../../../../components/loading/GlobalLoading"
|
|
||||||
|
|
||||||
const ServerGlobal = dynamic(() => import("./Global"), {
|
const ServerGlobal = dynamic(() => import("./Global"), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
loading: () => <GlobalLoading />,
|
loading: () => <GlobalLoading />,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import ServerListClient from "./ClientComponents/main/ServerListClient"
|
import ServerListClient from "@/app/(main)/ClientComponents/main/ServerListClient"
|
||||||
import ServerOverviewClient from "./ClientComponents/main/ServerOverviewClient"
|
import ServerOverviewClient from "@/app/(main)/ClientComponents/main/ServerOverviewClient"
|
||||||
|
|
||||||
export default async function Home() {
|
export default async function Home() {
|
||||||
return (
|
return (
|
||||||
|
@ -3,13 +3,12 @@
|
|||||||
import { NetworkChartClient } from "@/app/(main)/ClientComponents/detail/NetworkChart"
|
import { NetworkChartClient } from "@/app/(main)/ClientComponents/detail/NetworkChart"
|
||||||
import ServerDetailChartClient from "@/app/(main)/ClientComponents/detail/ServerDetailChartClient"
|
import ServerDetailChartClient from "@/app/(main)/ClientComponents/detail/ServerDetailChartClient"
|
||||||
import ServerDetailClient from "@/app/(main)/ClientComponents/detail/ServerDetailClient"
|
import ServerDetailClient from "@/app/(main)/ClientComponents/detail/ServerDetailClient"
|
||||||
|
import ServerIPInfo from "@/app/(main)/ClientComponents/detail/ServerIPInfo"
|
||||||
import TabSwitch from "@/components/TabSwitch"
|
import TabSwitch from "@/components/TabSwitch"
|
||||||
import { Separator } from "@/components/ui/separator"
|
import { Separator } from "@/components/ui/separator"
|
||||||
import getEnv from "@/lib/env-entry"
|
import getEnv from "@/lib/env-entry"
|
||||||
import { use, useState } from "react"
|
import { use, useState } from "react"
|
||||||
|
|
||||||
import ServerIPInfo from "../../ClientComponents/detail/ServerIPInfo"
|
|
||||||
|
|
||||||
export default function Page(props: { params: Promise<{ id: string }> }) {
|
export default function Page(props: { params: Promise<{ id: string }> }) {
|
||||||
const params = use(props.params)
|
const params = use(props.params)
|
||||||
const tabs = ["Detail", "Network"]
|
const tabs = ["Detail", "Network"]
|
||||||
|
@ -20,7 +20,7 @@ interface ServerDataContextType {
|
|||||||
|
|
||||||
const ServerDataContext = createContext<ServerDataContextType | undefined>(undefined)
|
const ServerDataContext = createContext<ServerDataContextType | undefined>(undefined)
|
||||||
|
|
||||||
const MAX_HISTORY_LENGTH = 30
|
export const MAX_HISTORY_LENGTH = 30
|
||||||
|
|
||||||
export function ServerDataProvider({ children }: { children: ReactNode }) {
|
export function ServerDataProvider({ children }: { children: ReactNode }) {
|
||||||
const [history, setHistory] = useState<ServerDataWithTimestamp[]>([])
|
const [history, setHistory] = useState<ServerDataWithTimestamp[]>([])
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
|
import Footer from "@/app/(main)/footer"
|
||||||
|
import Header from "@/app/(main)/header"
|
||||||
import { useTranslations } from "next-intl"
|
import { useTranslations } from "next-intl"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
|
|
||||||
import Footer from "./(main)/footer"
|
|
||||||
import Header from "./(main)/header"
|
|
||||||
|
|
||||||
export default function NotFoundPage() {
|
export default function NotFoundPage() {
|
||||||
const t = useTranslations("NotFoundPage")
|
const t = useTranslations("NotFoundPage")
|
||||||
return (
|
return (
|
||||||
|
3
auth.ts
3
auth.ts
@ -1,8 +1,7 @@
|
|||||||
|
import getEnv from "@/lib/env-entry"
|
||||||
import NextAuth from "next-auth"
|
import NextAuth from "next-auth"
|
||||||
import CredentialsProvider from "next-auth/providers/credentials"
|
import CredentialsProvider from "next-auth/providers/credentials"
|
||||||
|
|
||||||
import getEnv from "./lib/env-entry"
|
|
||||||
|
|
||||||
export const { handlers, signIn, signOut, auth } = NextAuth({
|
export const { handlers, signIn, signOut, auth } = NextAuth({
|
||||||
secret: process.env.AUTH_SECRET ?? "this_is_nezha_dash_web_secret",
|
secret: process.env.AUTH_SECRET ?? "this_is_nezha_dash_web_secret",
|
||||||
trustHost: (process.env.AUTH_TRUST_HOST as boolean | undefined) ?? true,
|
trustHost: (process.env.AUTH_TRUST_HOST as boolean | undefined) ?? true,
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { useFilter } from "@/lib/network-filter-context"
|
|
||||||
import { useStatus } from "@/lib/status-context"
|
|
||||||
import { ServerStackIcon } from "@heroicons/react/20/solid"
|
|
||||||
import { useRouter } from "next/navigation"
|
|
||||||
import { useEffect } from "react"
|
|
||||||
|
|
||||||
export default function GlobalBackButton() {
|
|
||||||
const router = useRouter()
|
|
||||||
const { setStatus } = useStatus()
|
|
||||||
const { setFilter } = useFilter()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setStatus("all")
|
|
||||||
setFilter(false)
|
|
||||||
sessionStorage.removeItem("selectedTag")
|
|
||||||
router.prefetch(`/`)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
router.push(`/`)
|
|
||||||
}}
|
|
||||||
className="rounded-[50px] mt-[1px] w-fit text-white cursor-pointer [text-shadow:_0_1px_0_rgb(0_0_0_/_20%)] bg-green-600 hover:bg-green-500 p-[10px] transition-all shadow-[inset_0_1px_0_rgba(255,255,255,0.2)] hover:shadow-[inset_0_1px_0_rgba(0,0,0,0.2)] "
|
|
||||||
>
|
|
||||||
<ServerStackIcon className="size-[13px]" />
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
}
|
|
@ -41,7 +41,7 @@ export function LanguageSwitcher() {
|
|||||||
onSelect={(e) => handleSelect(e, item.code)}
|
onSelect={(e) => handleSelect(e, item.code)}
|
||||||
className={cn(
|
className={cn(
|
||||||
{
|
{
|
||||||
"bg-muted gap-3": locale === item.code,
|
"bg-muted gap-3 font-semibold": locale === item.code,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rounded-t-[5px]": index === localeItems.length - 1,
|
"rounded-t-[5px]": index === localeItems.length - 1,
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
import { NezhaAPISafe } from "@/app/types/nezha-api"
|
|
||||||
import { cn, formatBytes } from "@/lib/utils"
|
|
||||||
import { useTranslations } from "next-intl"
|
|
||||||
|
|
||||||
export function ServerCardPopoverCard({
|
|
||||||
className,
|
|
||||||
title,
|
|
||||||
content,
|
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
className?: string
|
|
||||||
title: string
|
|
||||||
content?: string
|
|
||||||
children?: React.ReactNode
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className={cn("mb-[6px] flex w-full flex-col", className)}>
|
|
||||||
<div className="text-sm font-semibold">{title}</div>
|
|
||||||
{children ? children : <div className="break-all text-xs font-medium">{content}</div>}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function ServerCardPopover({
|
|
||||||
host,
|
|
||||||
status,
|
|
||||||
}: {
|
|
||||||
host: NezhaAPISafe["host"]
|
|
||||||
status: NezhaAPISafe["status"]
|
|
||||||
}) {
|
|
||||||
const t = useTranslations("ServerCardPopover")
|
|
||||||
return (
|
|
||||||
<section className="max-w-[300px]">
|
|
||||||
<ServerCardPopoverCard
|
|
||||||
title={t("System")}
|
|
||||||
content={`${host.Platform}-${host.PlatformVersion} [${host.Virtualization}: ${host.Arch}]`}
|
|
||||||
/>
|
|
||||||
<ServerCardPopoverCard
|
|
||||||
title={t("CPU")}
|
|
||||||
content={`${host.CPU.map((item) => item).join(", ")}`}
|
|
||||||
/>
|
|
||||||
<ServerCardPopoverCard
|
|
||||||
title={t("Mem")}
|
|
||||||
content={`${formatBytes(status.MemUsed)} / ${formatBytes(host.MemTotal)}`}
|
|
||||||
/>
|
|
||||||
<ServerCardPopoverCard
|
|
||||||
title={t("STG")}
|
|
||||||
content={`${formatBytes(status.DiskUsed)} / ${formatBytes(host.DiskTotal)}`}
|
|
||||||
/>
|
|
||||||
<ServerCardPopoverCard
|
|
||||||
title={t("Swap")}
|
|
||||||
content={`${formatBytes(status.SwapUsed)} / ${formatBytes(host.SwapTotal)}`}
|
|
||||||
/>
|
|
||||||
<ServerCardPopoverCard
|
|
||||||
title={t("Network")}
|
|
||||||
content={`${formatBytes(status.NetOutTransfer)} / ${formatBytes(status.NetInTransfer)}`}
|
|
||||||
/>
|
|
||||||
<ServerCardPopoverCard
|
|
||||||
title={t("Load")}
|
|
||||||
content={`${status.Load1.toFixed(2)} / ${status.Load5.toFixed(2)} / ${status.Load15.toFixed(2)}`}
|
|
||||||
/>
|
|
||||||
<ServerCardPopoverCard
|
|
||||||
className="mb-0"
|
|
||||||
title={t("Online")}
|
|
||||||
content={`${(status.Uptime / 86400).toFixed(0)} Days`}
|
|
||||||
/>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
@ -37,19 +37,19 @@ export function ModeToggle() {
|
|||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="flex flex-col gap-0.5" align="end">
|
<DropdownMenuContent className="flex flex-col gap-0.5" align="end">
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className={cn("rounded-b-[5px]", { "gap-3 bg-muted": theme === "light" })}
|
className={cn("rounded-b-[5px]", { "gap-3 bg-muted font-semibold": theme === "light" })}
|
||||||
onSelect={(e) => handleSelect(e, "light")}
|
onSelect={(e) => handleSelect(e, "light")}
|
||||||
>
|
>
|
||||||
{t("Light")} {theme === "light" && <CheckCircleIcon className="size-4" />}
|
{t("Light")} {theme === "light" && <CheckCircleIcon className="size-4" />}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className={cn("rounded-[5px]", { "gap-3 bg-muted": theme === "dark" })}
|
className={cn("rounded-[5px]", { "gap-3 bg-muted font-semibold": theme === "dark" })}
|
||||||
onSelect={(e) => handleSelect(e, "dark")}
|
onSelect={(e) => handleSelect(e, "dark")}
|
||||||
>
|
>
|
||||||
{t("Dark")} {theme === "dark" && <CheckCircleIcon className="size-4" />}
|
{t("Dark")} {theme === "dark" && <CheckCircleIcon className="size-4" />}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className={cn("rounded-t-[5px]", { "gap-3 bg-muted": theme === "system" })}
|
className={cn("rounded-t-[5px]", { "gap-3 bg-muted font-semibold": theme === "system" })}
|
||||||
onSelect={(e) => handleSelect(e, "system")}
|
onSelect={(e) => handleSelect(e, "system")}
|
||||||
>
|
>
|
||||||
{t("System")} {theme === "system" && <CheckCircleIcon className="size-4" />}
|
{t("System")} {theme === "system" && <CheckCircleIcon className="size-4" />}
|
||||||
|
@ -80,7 +80,7 @@ const DropdownMenuItem = React.forwardRef<
|
|||||||
<DropdownMenuPrimitive.Item
|
<DropdownMenuPrimitive.Item
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative flex cursor-default select-none items-center rounded-[10px] px-2 py-1.5 text-xs font-medium outline-hidden transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
"relative flex cursor-default select-none items-center rounded-[10px] px-2 py-1.5 text-xs font-normal outline-hidden transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
||||||
inset && "pl-8",
|
inset && "pl-8",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
"@radix-ui/react-slot": "^1.1.1",
|
"@radix-ui/react-slot": "^1.1.1",
|
||||||
"@radix-ui/react-switch": "^1.1.2",
|
"@radix-ui/react-switch": "^1.1.2",
|
||||||
"@radix-ui/react-tooltip": "^1.1.6",
|
"@radix-ui/react-tooltip": "^1.1.6",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^5.2.0",
|
"@trivago/prettier-plugin-sort-imports": "^5.2.1",
|
||||||
"@turf/turf": "^7.2.0",
|
"@turf/turf": "^7.2.0",
|
||||||
"@types/d3-geo": "^3.1.0",
|
"@types/d3-geo": "^3.1.0",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
@ -64,7 +64,7 @@
|
|||||||
"@biomejs/biome": "1.9.4",
|
"@biomejs/biome": "1.9.4",
|
||||||
"@next/bundle-analyzer": "^15.1.3",
|
"@next/bundle-analyzer": "^15.1.3",
|
||||||
"@tailwindcss/postcss": "^4.0.0-beta.8",
|
"@tailwindcss/postcss": "^4.0.0-beta.8",
|
||||||
"@types/node": "^22.10.2",
|
"@types/node": "^22.10.5",
|
||||||
"@types/react": "^19.0.2",
|
"@types/react": "^19.0.2",
|
||||||
"@types/react-dom": "^19.0.2",
|
"@types/react-dom": "^19.0.2",
|
||||||
"eslint-config-next": "^15.1.3",
|
"eslint-config-next": "^15.1.3",
|
||||||
@ -73,7 +73,7 @@
|
|||||||
"postcss": "^8.4.49",
|
"postcss": "^8.4.49",
|
||||||
"tailwindcss": "^4.0.0-beta.8",
|
"tailwindcss": "^4.0.0-beta.8",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.7.2",
|
||||||
"vercel": "^39.2.2"
|
"vercel": "^39.2.4"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"react-is": "^19.0.0-rc-69d4b800-20241021"
|
"react-is": "^19.0.0-rc-69d4b800-20241021"
|
||||||
|
Loading…
Reference in New Issue
Block a user