diff --git a/src/app/[orgId]/resources/[resourceId]/components/CustomDomainInput.tsx b/src/app/[orgId]/resources/[resourceId]/components/CustomDomainInput.tsx index 8f787db0..d03b9333 100644 --- a/src/app/[orgId]/resources/[resourceId]/components/CustomDomainInput.tsx +++ b/src/app/[orgId]/resources/[resourceId]/components/CustomDomainInput.tsx @@ -1,45 +1,47 @@ -"use client" +"use client"; -import * as React from "react" -import { Input } from "@/components/ui/input" +import * as React from "react"; +import { Input } from "@/components/ui/input"; interface CustomDomainInputProps { - domainSuffix: string - placeholder?: string - onChange?: (value: string) => void + domainSuffix: string; + placeholder?: string; + onChange?: (value: string) => void; } -export default function CustomDomainInput({ - domainSuffix, - placeholder = "Enter subdomain", - onChange -}: CustomDomainInputProps = { - domainSuffix: ".example.com" -}) { - const [value, setValue] = React.useState("") +export default function CustomDomainInput( + { + domainSuffix, + placeholder = "Enter subdomain", + onChange, + }: CustomDomainInputProps = { + domainSuffix: ".example.com", + }, +) { + const [value, setValue] = React.useState(""); - const handleChange = (event: React.ChangeEvent) => { - const newValue = event.target.value - setValue(newValue) - if (onChange) { - onChange(newValue) - } - } + const handleChange = (event: React.ChangeEvent) => { + const newValue = event.target.value; + setValue(newValue); + if (onChange) { + onChange(newValue); + } + }; - return ( -
-
- -
- {domainSuffix} + return ( +
+
+ +
+ {domainSuffix} +
+
-
-
- ) -} \ No newline at end of file + ); +} diff --git a/src/app/[orgId]/resources/[resourceId]/targets/page.tsx b/src/app/[orgId]/resources/[resourceId]/targets/page.tsx index b237bcdd..23021c38 100644 --- a/src/app/[orgId]/resources/[resourceId]/targets/page.tsx +++ b/src/app/[orgId]/resources/[resourceId]/targets/page.tsx @@ -1,32 +1,45 @@ -"use client" +"use client"; -import { useEffect, useState } from "react" -import { PlusCircle, Trash2, Server, Globe, Cpu, Power } from "lucide-react" -import { Button } from "@/components/ui/button" -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" -import { Switch } from "@/components/ui/switch" -import { Badge } from "@/components/ui/badge" -import api from "@app/api" -import { AxiosResponse } from "axios" -import { ListTargetsResponse } from "@server/routers/target/listTargets" +import { useEffect, useState } from "react"; +import { PlusCircle, Trash2, Server, Globe, Cpu } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Switch } from "@/components/ui/switch"; +import { Badge } from "@/components/ui/badge"; +import api from "@app/api"; +import { AxiosResponse } from "axios"; +import { ListTargetsResponse } from "@server/routers/target/listTargets"; const isValidIPAddress = (ip: string) => { - const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; + const ipv4Regex = + /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; return ipv4Regex.test(ip); -} +}; -export default function ReverseProxyTargets({ params }: { params: { resourceId: string } }) { - const [targets, setTargets] = useState([]) - const [nextId, setNextId] = useState(1) - const [ipError, setIpError] = useState("") +export default function ReverseProxyTargets({ + params, +}: { + params: { resourceId: string }; +}) { + const [targets, setTargets] = useState([]); + const [nextId, setNextId] = useState(1); + const [ipError, setIpError] = useState(""); useEffect(() => { if (typeof window !== "undefined") { const fetchSites = async () => { - const res = await api.get>(`/resource/${params.resourceId}/targets`); + const res = await api.get>( + `/resource/${params.resourceId}/targets`, + ); setTargets(res.data.data.targets); }; fetchSites(); @@ -39,7 +52,7 @@ export default function ReverseProxyTargets({ params }: { params: { resourceId: method: "http", port: 80, protocol: "TCP", - }) + }); const addTarget = () => { if (!isValidIPAddress(newTarget.ip)) { @@ -50,64 +63,62 @@ export default function ReverseProxyTargets({ params }: { params: { resourceId: api.put(`/resource/${params.resourceId}/target`, { ...newTarget, - resourceId: undefined + resourceId: undefined, }) .catch((err) => { - console.error(err) - - }).then((res) => { + console.error(err); + }) + .then((res) => { // console.log(res) - setTargets([...targets, { ...newTarget, targetId: nextId, enabled: true }]) - setNextId(nextId + 1) + setTargets([ + ...targets, + { ...newTarget, targetId: nextId, enabled: true }, + ]); + setNextId(nextId + 1); setNewTarget({ resourceId: params.resourceId, ip: "", method: "GET", port: 80, protocol: "http", - }) + }); }); - - } + }; const removeTarget = (targetId: number) => { api.delete(`/target/${targetId}`) .catch((err) => { - console.error(err) - }).then((res) => { - setTargets(targets.filter((target) => target.targetId !== targetId)); + console.error(err); + }) + .then((res) => { + setTargets( + targets.filter((target) => target.targetId !== targetId), + ); }); - } + }; const toggleTarget = (targetId: number) => { setTargets( targets.map((target) => - target.targetId === targetId ? { ...target, enabled: !target.enabled } : target - ) - ) - api.post(`/target/${targetId}`, { enabled: !targets.find((target) => target.targetId === targetId)?.enabled }) - .catch((err) => { - console.error(err) - }).then((res) => { - console.log(res) - }); - - // Add a visual feedback - const targetElement = document.getElementById(`target-${targetId}`) - if (targetElement) { - targetElement.classList.add('scale-105', 'transition-transform') - setTimeout(() => { - targetElement.classList.remove('scale-105', 'transition-transform') - }, 200) - } - } + target.targetId === targetId + ? { ...target, enabled: !target.enabled } + : target, + ), + ); + api.post(`/target/${targetId}`, { + enabled: !targets.find((target) => target.targetId === targetId) + ?.enabled, + }).catch((err) => { + console.error(err); + }); + }; return (
{ - e.preventDefault() - addTarget() + e.preventDefault(); + addTarget(); }} className="space-y-4" > @@ -118,18 +129,25 @@ export default function ReverseProxyTargets({ params }: { params: { resourceId: id="ip" value={newTarget.ip} onChange={(e) => { - setNewTarget({ ...newTarget, ip: e.target.value }) - setIpError("") + setNewTarget({ + ...newTarget, + ip: e.target.value, + }); + setIpError(""); }} required /> - {ipError &&

{ipError}

} + {ipError && ( +

{ipError}

+ )}
setNewTarget({ ...newTarget, protocol: value })} + onValueChange={(value) => + setNewTarget({ ...newTarget, protocol: value }) + } > @@ -172,8 +197,12 @@ export default function ReverseProxyTargets({ params }: { params: { resourceId:
- {targets.map((target) => ( - + {targets.map((target, i) => ( + @@ -182,13 +211,17 @@ export default function ReverseProxyTargets({ params }: { params: { resourceId:
toggleTarget(target.targetId)} + onCheckedChange={() => + toggleTarget(target.targetId) + } /> @@ -198,15 +231,35 @@ export default function ReverseProxyTargets({ params }: { params: { resourceId:
- {target.ip}:{target.port} + + {target.ip}:{target.port} +
- {target.resourceId} + + {target.resourceId} +
- {target.method} - {target.protocol?.toUpperCase()} + + {target.method} + + + {target.protocol?.toUpperCase()} +
@@ -214,5 +267,5 @@ export default function ReverseProxyTargets({ params }: { params: { resourceId: ))}
- ) -} \ No newline at end of file + ); +}