feat: add tunnel configuration tools

This commit is contained in:
2025-09-06 18:53:38 +07:00
parent d5ffb87e1a
commit 9701d8766e
7 changed files with 1655 additions and 313 deletions

View File

@ -1,64 +0,0 @@
"use client"
import { useState } from "react"
export default function Card() {
const [copied, setCopied] = useState(false)
const command = "ssh id.tunnl.live -p 2200 -R 443:localhost:8000"
const copyToClipboard = () => {
navigator.clipboard.writeText(command)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
return (
<div className="mb-16">
<h2 className="text-2xl font-bold mb-6">Connect with a single command</h2>
<div className="relative">
<div className="bg-gray-900 rounded-lg p-4 border border-gray-800 font-mono text-sm sm:text-base overflow-x-auto">
<pre className="whitespace-pre-wrap break-all sm:break-normal">{command}</pre>
</div>
<button
onClick={copyToClipboard}
className="absolute right-3 top-3 h-8 w-8 flex items-center justify-center rounded-md text-gray-400 hover:text-white hover:bg-gray-800"
aria-label="Copy command"
>
{copied ? (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-emerald-400"
>
<path d="M20 6 9 17l-5-5" />
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
<path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
</svg>
)}
</button>
</div>
<p className="mt-4 text-sm text-gray-400">
This command creates a secure tunnel from our server to your localhost:8000
</p>
</div>
)
}

View File

@ -1,11 +1,23 @@
import Card from "./card"
"use client"
import { useState } from "react"
import TunnelConfig, { type TunnelConfig as TunnelConfigType, type Server } from "@/components/tunnel-config"
const defaultConfig: TunnelConfigType = {
type: "http",
serverPort: 443,
localPort: 8000,
}
export default function Home() {
const [selectedServer, setSelectedServer] = useState<Server | null>(null)
const [tunnelConfig, setTunnelConfig] = useState<TunnelConfigType>(defaultConfig)
return (
<div className="flex min-h-screen flex-col bg-gray-950 text-white">
<main className="flex-1 flex flex-col items-center justify-center px-4">
<div className="w-full max-w-3xl mx-auto text-center">
<div className="mb-12">
<main className="flex-1 flex flex-col items-center justify-center px-4 py-8">
<div className="w-full max-w-4xl mx-auto">
<div className="text-center mb-12">
<h1 className="text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl mb-6">
<span className="text-emerald-400">tunnl</span>.live
</h1>
@ -13,85 +25,94 @@ export default function Home() {
Expose your local services to the internet securely with our fast and reliable SSH tunneling service.
</p>
</div>
<Card />
<div className="grid gap-8 md:grid-cols-3 mb-16">
<div className="bg-gray-900 p-6 rounded-lg border border-gray-800">
<div className="mb-4 inline-block rounded-full bg-emerald-950 p-3">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-emerald-400"
>
<circle cx="12" cy="12" r="10" />
<path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" />
<path d="M2 12h20" />
</svg>
</div>
<h3 className="text-xl font-bold mb-2">Global Network</h3>
<p className="text-gray-400">
We offer low-latency, high-availability servers located in Singapore for optimal performance.
</p>
</div>
<div className="bg-gray-900 p-6 rounded-lg border border-gray-800">
<div className="mb-4 inline-block rounded-full bg-emerald-950 p-3">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-emerald-400"
>
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
</svg>
</div>
<h3 className="text-xl font-bold mb-2">Secure by Default</h3>
<p className="text-gray-400">
End-to-end encryption with SSH ensures your data remains private and secure.
</p>
</div>
<div className="bg-gray-900 p-6 rounded-lg border border-gray-800">
<div className="mb-4 inline-block rounded-full bg-emerald-950 p-3">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-emerald-400"
>
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
<polyline points="15 3 21 3 21 9" />
<line x1="10" x2="21" y1="14" y2="3" />
</svg>
</div>
<h3 className="text-xl font-bold mb-2">Easy Sharing</h3>
<p className="text-gray-400">
Share your local development with clients or teammates without complex setup.
</p>
</div>
</div>
<div className="text-center mb-8">
<h2 className="text-2xl font-bold mb-4">100% Free Service</h2>
<p className="text-gray-400 max-w-2xl mx-auto">
No registration required. Just run the command and start using the tunnel immediately.
</p>
<TunnelConfig
config={tunnelConfig}
onConfigChange={setTunnelConfig}
selectedServer={selectedServer}
onServerSelect={setSelectedServer}
/>
<div className="max-w-3xl mx-auto">
<div className="grid gap-8 md:grid-cols-3 mb-16">
<div className="bg-gray-900 p-6 rounded-lg border border-gray-800">
<div className="mb-4 inline-block rounded-full bg-emerald-950 p-3">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-emerald-400"
>
<circle cx="12" cy="12" r="10" />
<path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" />
<path d="M2 12h20" />
</svg>
</div>
<h3 className="text-xl font-bold mb-2">Global Network</h3>
<p className="text-gray-400">
Choose from servers in US, Singapore, and Indonesia for optimal performance.
</p>
</div>
<div className="bg-gray-900 p-6 rounded-lg border border-gray-800">
<div className="mb-4 inline-block rounded-full bg-emerald-950 p-3">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-emerald-400"
>
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
</svg>
</div>
<h3 className="text-xl font-bold mb-2">Secure by Default</h3>
<p className="text-gray-400">
End-to-end encryption with SSH ensures your data remains private and secure.
</p>
</div>
<div className="bg-gray-900 p-6 rounded-lg border border-gray-800">
<div className="mb-4 inline-block rounded-full bg-emerald-950 p-3">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-emerald-400"
>
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1-2-2h6" />
<polyline points="15 3 21 3 21 9" />
<line x1="10" x2="21" y1="14" y2="3" />
</svg>
</div>
<h3 className="text-xl font-bold mb-2">Flexible Configuration</h3>
<p className="text-gray-400">
Support for both HTTP/HTTPS and TCP tunneling with custom port configuration.
</p>
</div>
</div>
<div className="text-center mb-8">
<h2 className="text-2xl font-bold mb-4">100% Free Service</h2>
<p className="text-gray-400 max-w-2xl mx-auto">
No registration required. Just run the command and start using the tunnel immediately.
</p>
</div>
</div>
</div>
</main>

View File

@ -0,0 +1,106 @@
"use client"
import Image from "next/image"
import Link from "next/link"
export default function TunnelNotFound() {
const exampleUrl = "example.com"
return (
<div className="flex min-h-screen flex-col bg-gray-950 text-white">
<main className="flex-1 flex flex-col items-center justify-center px-4 py-8">
<div className="w-full max-w-2xl mx-auto text-center">
{/* Mascot */}
<div className="mb-8">
<Image
src="/mascot-confused.png"
alt="Confused tunnel mascot"
width={200}
height={200}
className="mx-auto"
/>
</div>
{/* Error Message */}
<div className="mb-12">
<h1 className="text-4xl font-bold mb-6">Tunnel Not Found</h1>
<p className="text-gray-400 mb-6 text-lg">We couldn't find an active tunnel for:</p>
<div className="bg-gray-900 rounded-lg p-4 border border-gray-800 font-mono text-emerald-400 text-xl max-w-md mx-auto mb-8">
{exampleUrl}
</div>
<p className="text-gray-300 text-lg">This means no SSH tunnel is currently running for this domain.</p>
</div>
{/* Instructions */}
<div className="bg-gray-900 rounded-lg p-8 border border-gray-800 mb-8 text-left">
<h2 className="text-xl font-bold mb-6 text-center">To create a tunnel:</h2>
<div className="space-y-4">
<div className="flex items-start gap-4">
<span className="bg-emerald-600 text-white rounded-full w-8 h-8 flex items-center justify-center text-sm font-bold flex-shrink-0 mt-1">
1
</span>
<div>
<p className="text-gray-300 font-medium">Go to the main page</p>
<p className="text-gray-400 text-sm">Configure your tunnel settings and choose a server</p>
</div>
</div>
<div className="flex items-start gap-4">
<span className="bg-emerald-600 text-white rounded-full w-8 h-8 flex items-center justify-center text-sm font-bold flex-shrink-0 mt-1">
2
</span>
<div>
<p className="text-gray-300 font-medium">Make sure your local service is running</p>
<p className="text-gray-400 text-sm">Your application should be accessible on localhost</p>
</div>
</div>
<div className="flex items-start gap-4">
<span className="bg-emerald-600 text-white rounded-full w-8 h-8 flex items-center justify-center text-sm font-bold flex-shrink-0 mt-1">
3
</span>
<div>
<p className="text-gray-300 font-medium">Run the SSH command</p>
<p className="text-gray-400 text-sm">Copy and paste the generated command into your terminal</p>
</div>
</div>
<div className="flex items-start gap-4">
<span className="bg-emerald-600 text-white rounded-full w-8 h-8 flex items-center justify-center text-sm font-bold flex-shrink-0 mt-1">
4
</span>
<div>
<p className="text-gray-300 font-medium">Access your tunnel</p>
<p className="text-gray-400 text-sm">Your service will be available through the tunnel URL</p>
</div>
</div>
</div>
</div>
{/* Call to Action */}
<div className="space-y-4">
<Link
href="/"
className="inline-flex items-center gap-3 bg-emerald-600 hover:bg-emerald-700 text-white px-6 py-3 rounded-lg font-medium transition-colors"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M5 12h14" />
<path d="M12 5l7 7-7 7" />
</svg>
Create Your Tunnel
</Link>
<p className="text-gray-400 text-sm">Need help? Check our documentation or contact support.</p>
</div>
</div>
</main>
</div>
)
}