diff --git a/app/api/caddy/routes/route.ts b/app/api/caddy/routes/route.ts index 9f89531..c898e2e 100644 --- a/app/api/caddy/routes/route.ts +++ b/app/api/caddy/routes/route.ts @@ -1,5 +1,6 @@ import { getConfig, getRoutes, getServer } from '@/lib/serverActions'; import { NextApiRequest } from 'next'; +import { revalidateTag } from 'next/cache'; import { NextResponse } from 'next/server'; export async function GET() { @@ -29,6 +30,8 @@ export async function DELETE(req: Request) { let targetRoute: Route = routesMap.filter((r) => (JSON.stringify(r.match[0]) === JSON.stringify(route.match[0]))).values().next().value; let index = routesMap.indexOf(targetRoute); + + revalidateTag('routes'); if(index == -1) return new NextResponse(JSON.stringify({error: true, message: "Route not found"}), { status: 404, diff --git a/app/page.tsx b/app/page.tsx index 5688305..dbd2084 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,26 +1,22 @@ "use client" -import { CardTitle, Card, CardDescription, CardHeader, CardContent } from '@/components/ui/card'; -import { getRoutes } from '@/lib/serverActions'; +import { CardTitle, Card, CardDescription, CardHeader, CardContent, CardFooter } from '@/components/ui/card'; import RouteCards from '@/components/RouteCards'; -import { useEffect, useState } from 'react'; +import { Button } from '@/components/ui/button'; +import { useRoutes } from '@/lib/clientActions'; -async function fetchRoutes() { - let routes: Route[] = await getRoutes(); - return routes; -} export default function Home() { - useEffect(() => { - async function fetchData() { - const data: Route[] = await fetchRoutes(); - setRoutes(data); - } - fetchData(); - }, []); + const { data: routes, error, isLoading } = useRoutes(); + let routesMap: Route[] = routes as Route[]; - const [routes, setRoutes] = useState([]) + if (error) return
Error loading routes
+ if (isLoading) return ( +
+ Loading... +
+ ) return (
@@ -31,14 +27,17 @@ export default function Home() { Amount of configured routes -
-

{routes.length}

+
+

{routesMap.length}

+ + +
- +
) diff --git a/components/RouteCards.tsx b/components/RouteCards.tsx index f43409a..1c3ecc7 100644 --- a/components/RouteCards.tsx +++ b/components/RouteCards.tsx @@ -3,83 +3,54 @@ import { Button } from '@/components/ui/button'; import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "./ui/card"; import { getHosts, getRouteUpstreams } from '@/lib/utils'; -import { deleteRoute } from '@/lib/serverActions'; import { toast } from './ui/use-toast'; -import React, { useState } from 'react'; +import React from 'react'; +import useSWRMutation from 'swr/mutation'; +import { deleteRoute } from '@/lib/clientActions'; -class RouteCards extends React.Component<{routes: Route[]}> { - constructor(props: { routes: Route[] }) { - super(props); - this.handleClick = this.handleClick.bind(this); - } +export default function RouteCards({ routes }: { routes: Route[] }) { - state = { - routes: this.props.routes, - } - - componentDidUpdate(prevProps: Readonly<{ routes: Route[]; }>, prevState: Readonly<{}>) { - if (this.props.routes !== prevProps.routes) { - this.setState({ - routes: this.props.routes + const { trigger } = useSWRMutation("/api/caddy/routes", deleteRoute, { + onError: () => { + return toast({ + title: "Error", + description: "There was an error deleting the route", + variant: "destructive" + }); + }, + onSuccess: () => { + toast({ + title: "Success", + description: "Route deleted successfully!", + variant: "success" }); } - } - - handleDelete = async (route: Route) => { - let res = await deleteRoute(route); - - if (res.error) return toast({ - title: "Error", - description: res.message, - variant: "destructive" - }); - - this.state.routes.splice(this.state.routes.indexOf(route), 1) - - this.setState({ - routes: this.state.routes - }); - - return toast({ - title: "Success", - description: "Route deleted successfully!", - variant: "success" - }); - } - - - - - handleClick = (route: Route) => { - console.log(route); - } - - render() { - return ( - this.state.routes.map((route, index) => ( -
- - - {getHosts(route).values().next().value} - {getHosts(route).map((route => {route}))} - - - -

- Tunneling to -

-

{getRouteUpstreams(route)?.map((upstream => upstream.dial))}

-
- - - - -
-
- )) - ) - } + }); + return ( + routes.map((route, index) => ( +
+ + + {getHosts(route).values().next().value} + {getHosts(route).map((route => {route}))} + + + +

+ Tunneling to +

+

{getRouteUpstreams(route)?.map((upstream => upstream.dial))}

+
+ + + + +
+
+ )) + ) } -export default RouteCards; \ No newline at end of file + + diff --git a/package.json b/package.json index 6816553..f6b6d97 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "next-themes": "^0.2.1", "react": "^18", "react-dom": "^18", + "swr": "^2.2.4", "tailwind-merge": "^2.0.0", "tailwindcss-animate": "^1.0.7" },