Skip to content

Commit da5bfbc

Browse files
committed
feat: integrate fetch registered domains
1 parent 7ac6fc7 commit da5bfbc

File tree

14 files changed

+324
-33
lines changed

14 files changed

+324
-33
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
"@radix-ui/react-dialog": "^1.1.6",
2727
"@radix-ui/react-dropdown-menu": "^2.1.6",
2828
"@radix-ui/react-label": "^2.1.2",
29+
"@radix-ui/react-separator": "^1.1.2",
2930
"@radix-ui/react-slot": "^1.1.2",
31+
"@radix-ui/react-tooltip": "^1.1.8",
3032
"@tabler/icons-react": "^3.31.0",
3133
"@tanstack/react-query": "^5.69.0",
3234
"axios": "^1.8.4",

pnpm-lock.yaml

Lines changed: 83 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/(ui)/(protected)/layout.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default function ProtectedLayout({ children }: { children: React.ReactNod
2727
if (userData) {
2828
setUser(userData)
2929
}
30-
}, [userData,setUser])
30+
}, [userData, setUser])
3131

3232
if (isLoadingProfile) {
3333
return (
@@ -38,9 +38,11 @@ export default function ProtectedLayout({ children }: { children: React.ReactNod
3838
if (checking) return null;
3939

4040
return (
41-
<div className="px-32">
41+
<div className="h-screen flex flex-col px-48 overflow-hidden">
4242
<TopHeader />
43-
{children}
43+
<div className="flex-1 px-4 pb-10 max-h-[86vh]">
44+
{children}
45+
</div>
4446
<ChangePassword
4547
title="Reset your password!"
4648
description="Please create a new password for your account."

src/app/(ui)/(protected)/page.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
1-
import PageHeader from "@/components/page-header"
1+
"use client";
2+
3+
import { BoxLoader } from "@/components/loader";
4+
import PageHeader from "@/components/page-header";
5+
import Proxies from "@/components/proxies/proxies";
6+
import { Separator } from "@/components/ui/separator";
7+
import { useGetRegisteredDomains } from "@/hooks/domains/domain.hooks";
8+
9+
export default function Home() {
10+
const { data, isLoading } = useGetRegisteredDomains();
211

3-
export default async function Home() {
412
return (
5-
<div className="mt-4 px-4">
13+
<div className="mt-4 px-4 mb-24 flex flex-col h-full">
614
<PageHeader
7-
title="Dashboard"
15+
title="Proxies"
816
description="Manage your proxies from here!"
917
showBackButton={false}
1018
/>
19+
<Separator />
20+
{isLoading ? (
21+
<BoxLoader height="h-[24vh]" />
22+
) : (
23+
<Proxies proxyData={data} />
24+
)}
1125
</div>
12-
)
26+
);
1327
}

src/app/(ui)/layout.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Toaster } from "@/components/ui/sonner";
66
import { QueryClientProvider } from "@tanstack/react-query";
77
import { useGetQueryClient } from "@/hooks/query/useGetQueryClient";
88
import { useEffect } from "react";
9+
import { TooltipProvider } from "@/components/ui/tooltip";
910

1011
const geistSans = Geist({
1112
variable: "--font-geist-sans",
@@ -39,9 +40,11 @@ export default function RootLayout({
3940
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
4041
>
4142
<QueryClientProvider client={queryClient}>
42-
<main>
43-
{children}
44-
</main>
43+
<TooltipProvider>
44+
<main>
45+
{children}
46+
</main>
47+
</TooltipProvider>
4548

4649
<Toaster />
4750
</QueryClientProvider>

src/app/api/_services/dns/dns-service.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ async function checkDNS(domain: string): Promise<boolean> {
2020
* Check if the request reaches the proxy (Proxy Reachability check).
2121
*/
2222
async function checkProxyReachability(domain: string): Promise<boolean> {
23-
console.log("check reachabilt", domain)
2423
return new Promise((resolve) => {
2524
const options = {
2625
host: caddyServerIPAddress,

src/app/api/domain/config/route.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export async function GET() {
66
const caddyConfig = await getCaddyConfig();
77
return NextResponse.json(caddyConfig);
88
} catch (err) {
9-
console.log("error", err)
109
return NextResponse.json(
1110
{ error: 'Failed to retrieve Caddy configuration' },
1211
{ status: 500 }

src/app/api/domain/registered/route.ts

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,30 @@
1-
import { NextResponse } from 'next/server';
2-
import { checkDomain } from '../../_services/dns/dns-service';
3-
import prisma from '../../../../lib/prisma';
4-
import { DomainWithCheckResults } from '../domain-types';
1+
import { NextResponse } from "next/server";
2+
import { checkDomain } from "../../_services/dns/dns-service";
3+
import prisma from "../../../../lib/prisma";
4+
import { DomainWithCheckResults } from "../domain-types";
55

66
export async function GET() {
77
try {
88
const registeredDomains = await prisma.domains.findMany({});
99

10-
console.log(registeredDomains)
11-
12-
const domainsWithCheckResults: DomainWithCheckResults[] = []
10+
const domainsWithCheckResults: DomainWithCheckResults[] = [];
1311

1412
for (const domain of registeredDomains) {
15-
const domainCheckResults = await checkDomain(domain.incomingAddress);
16-
domainsWithCheckResults.push({
17-
...domain,
18-
checkResults: domainCheckResults,
19-
});
13+
const domainCheckResults = await checkDomain(domain.incomingAddress);
14+
domainsWithCheckResults.push({
15+
...domain,
16+
checkResults: domainCheckResults,
17+
});
2018
}
2119

22-
return NextResponse.json({
20+
return NextResponse.json({
2321
data: domainsWithCheckResults,
24-
total: domainsWithCheckResults.length
22+
total: domainsWithCheckResults.length,
2523
});
26-
2724
} catch (err) {
28-
console.log("Error",err)
25+
console.log("Error", err);
2926
return NextResponse.json(
30-
{ error: 'Failed to retrieve registered domains' },
27+
{ error: "Failed to retrieve registered domains" },
3128
{ status: 500 }
3229
);
3330
}

src/app/api/user/profile/route.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ export async function GET(req: NextRequest) {
99
}
1010
return NextResponse.json({ data: user });
1111
} catch (err) {
12-
console.log("error", err);
1312
return NextResponse.json(
1413
{ error: "Failed to retrieve user profile." },
1514
{ status: 500 }

src/components/proxies/proxies.tsx

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { DomainWithCheckResults } from "@/app/api/domain/domain-types";
2+
import { Check, X } from "lucide-react";
3+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/tooltip";
4+
5+
type Props = {
6+
proxyData: {
7+
data: DomainWithCheckResults[];
8+
total: number;
9+
} | undefined
10+
}
11+
12+
type ProxyRecordProps = {
13+
record: DomainWithCheckResults
14+
}
15+
16+
const ProxyRecord = ({ record }: ProxyRecordProps) => {
17+
return (
18+
<div className="flex flex-col items-start gap-1">
19+
<div className="font-semibold">
20+
{record.incomingAddress}
21+
</div>
22+
<div className="text-sm text-gray-500">
23+
Routes to <span className="font-bold text-gray-700">{record.destinationAddress}</span> on port <span className="font-bold text-gray-700">{record.port}</span>
24+
</div>
25+
</div>
26+
)
27+
}
28+
29+
const ProxyRecordCheckResults = ({ record }: ProxyRecordProps) => {
30+
return (
31+
<div className="flex items-center justify-end gap-6">
32+
<div className="flex items-center justify-start gap-1 text-md text-gray-500">
33+
<Tooltip>
34+
<TooltipTrigger asChild>
35+
<div className="flex items-center justify-start gap-1 text-md text-gray-500">
36+
DNS {record.checkResults.dnsCheck.result ? (
37+
<Check className="text-green-500" />
38+
) : (
39+
<X className="text-red-400" />
40+
)}
41+
</div>
42+
</TooltipTrigger>
43+
<TooltipContent>
44+
<p>{record.checkResults.dnsCheck.description}</p>
45+
</TooltipContent>
46+
</Tooltip>
47+
</div>
48+
49+
<div className="flex items-center justify-start gap-1 text-md text-gray-500">
50+
<Tooltip>
51+
<TooltipTrigger asChild>
52+
<div className="flex items-center justify-start gap-1 text-md text-gray-500">
53+
Resolving {record.checkResults.proxyReachability.result ? <Check className="text-green-500" /> : <X className="text-red-400" />}
54+
</div>
55+
</TooltipTrigger>
56+
<TooltipContent>
57+
<p>{record.checkResults.proxyReachability.description}</p>
58+
</TooltipContent>
59+
</Tooltip>
60+
</div>
61+
</div>
62+
)
63+
}
64+
65+
const Proxies = ({ proxyData }: Props) => {
66+
return (
67+
<div className="space-y-4 mt-2 overflow-y-scroll">
68+
<div>
69+
Found <span className="font-bold">{proxyData?.total}</span> record{proxyData && proxyData?.total > 1 ? 's.' : '.'}
70+
</div>
71+
<div>
72+
{proxyData?.data.map((record, index) => (
73+
<div key={index} className="border-l-4 border-gray-600 pl-4 pr-2 py-1 flex items-center justify-between">
74+
<ProxyRecord record={record} />
75+
<ProxyRecordCheckResults record={record} />
76+
</div>
77+
))}
78+
</div>
79+
</div>
80+
);
81+
};
82+
83+
export default Proxies;

src/components/top-header.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import ChangePassword from "./change-password"
77
import { useState } from "react"
88

99
const NAV_ITEMS = [
10-
{ name: "Dashboard", href: "/" },
10+
{ name: "Proxies", href: "/" },
1111
{ name: "API Keys", href: "/api-keys" },
1212
{ name: "Docs", href: "/docs" },
1313
];
@@ -52,7 +52,6 @@ const TopHeader = () => {
5252
<div className="flex items-center justify-end gap-2">
5353
<ProfileDropdown
5454
openPasswordDialog={openPasswordDialog}
55-
closePasswordDialog={closePasswordDialog}
5655
/>
5756
</div>
5857
</div>

0 commit comments

Comments
 (0)