feat: add routing and landing page

This commit is contained in:
2025-02-07 18:31:20 +07:00
parent d5829ffd0d
commit e6e9e25d8d
13 changed files with 1130 additions and 4 deletions

View File

@ -0,0 +1,88 @@
package indexView
import "tunnel_pls/view/layout"
templ Main(title string) {
@layout.Base(title) {
<div class="min-h-screen bg-gradient-to-b from-gray-900 to-gray-800 text-white">
<header class="container mx-auto px-4 py-8">
<nav class="flex justify-between items-center">
<h1 class="text-2xl font-bold">SSH Tunnel</h1>
<button class="px-4 py-2 border border-white rounded hover:bg-white hover:text-gray-900 transition-colors">Get Started</button>
</nav>
</header>
<main class="container mx-auto px-4 py-16 text-center">
<h2 class="text-4xl font-bold mb-6">Secure Remote Access Made Simple</h2>
<p class="text-xl mb-12 max-w-2xl mx-auto">
SSH Tunnel provides a secure way to access your local services remotely.
Connect to your development environment from anywhere, safely.
</p>
<div class="bg-gray-800 p-6 rounded-lg shadow-lg inline-block">
<h3 class="text-2xl font-semibold mb-4 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
Example Command
</h3>
<code id="sshCommand" class="text-green-400 text-lg block mb-4 bg-gray-900 p-4 rounded">
ssh tunnl.live -p 2200 -R 80:localhost:8000
</code>
<button id="copyButton" class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors flex items-center justify-center mx-auto">
Copy Command
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 ml-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
</svg>
</button>
</div>
<div class="mt-16 grid md:grid-cols-3 gap-8">
<div class="bg-gray-800 p-6 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 mx-auto mb-4 text-blue-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path>
</svg>
<h3 class="text-xl font-semibold mb-2">Secure</h3>
<p>End-to-end encryption ensures your data remains private and protected.</p>
</div>
<div class="bg-gray-800 p-6 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 mx-auto mb-4 text-green-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<h3 class="text-xl font-semibold mb-2">Easy to Use</h3>
<p>Simple command-line interface for quick setup and connection.</p>
</div>
<div class="bg-gray-800 p-6 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 mx-auto mb-4 text-purple-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
</svg>
<h3 class="text-xl font-semibold mb-2">Flexible</h3>
<p>Connect to various local services and ports with ease.</p>
</div>
</div>
</main>
<footer class="container mx-auto px-4 py-8 text-center text-gray-400">
<p>&copy; 2025 SSH Tunnel. All rights reserved.</p>
<div class="mt-4 flex justify-center space-x-4">
<a href="https://github.com/yourusername" target="_blank" rel="noopener noreferrer" class="hover:text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"></path>
</svg>
</a>
<a href="mailto:your.email@example.com" class="hover:text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
</svg>
</a>
</div>
</footer>
<script>
document.getElementById('copyButton').addEventListener('click', function() {
const sshCommand = document.getElementById('sshCommand').textContent;
navigator.clipboard.writeText(sshCommand).then(function() {
alert('Command copied to clipboard!');
}, function(err) {
console.error('Could not copy text: ', err);
});
});
</script>
</div>
}
}

60
view/index/index_templ.go Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,21 @@
package layout
templ Base(title string){
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Secure and reliable file hosting service. Upload, organize, and share your documents, images, videos, and more. Sign up now to keep your files always within reach." />
<meta name="keywords" content="file hosting, file sharing, cloud storage, data storage, secure file hosting, filekeeper, drive, mega" />
<meta name="author" content="Filekeeper" />
<link href="/public/output.css" rel="stylesheet"/>
<title>{ title }</title>
</head>
<body>
<div id="content">
{ children... }
</div>
</body>
</html>
}

View File

@ -0,0 +1,61 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.833
package layout
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
func Base(title string) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><meta name=\"description\" content=\"Secure and reliable file hosting service. Upload, organize, and share your documents, images, videos, and more. Sign up now to keep your files always within reach.\"><meta name=\"keywords\" content=\"file hosting, file sharing, cloud storage, data storage, secure file hosting, filekeeper, drive, mega\"><meta name=\"author\" content=\"Filekeeper\"><link href=\"/public/output.css\" rel=\"stylesheet\"><title>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 13, Col: 22}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</title></head><body><div id=\"content\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</div></body></html>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@ -0,0 +1,3 @@
<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><meta name=\"description\" content=\"Secure and reliable file hosting service. Upload, organize, and share your documents, images, videos, and more. Sign up now to keep your files always within reach.\"><meta name=\"keywords\" content=\"file hosting, file sharing, cloud storage, data storage, secure file hosting, filekeeper, drive, mega\"><meta name=\"author\" content=\"Filekeeper\"><link href=\"/public/output.css\" rel=\"stylesheet\"><title>
</title></head><body><div id=\"content\">
</div></body></html>