@@ -17,6 +17,31 @@ import Tooltip from '../components/Tooltip.astro';
1717 </p >
1818 </header >
1919
20+ <!-- Use-case cards -->
21+ <section class =" section" >
22+ <div class =" usecase-cards" >
23+ <button class =" usecase-card" data-usecase =" remote-db" >
24+ <span class =" usecase-card__icon" >🗄</span >
25+ <span class =" usecase-card__title" >Acessar banco remoto</span >
26+ <span class =" usecase-card__desc" >PostgreSQL, MySQL via túnel local</span >
27+ </button >
28+ <button class =" usecase-card" data-usecase =" expose-local" >
29+ <span class =" usecase-card__icon" >🌐</span >
30+ <span class =" usecase-card__title" >Expor servidor local</span >
31+ <span class =" usecase-card__desc" >Compartilhe seu dev server</span >
32+ </button >
33+ <button class =" usecase-card" data-usecase =" socks-proxy" >
34+ <span class =" usecase-card__icon" >🔒</span >
35+ <span class =" usecase-card__title" >Navegar via proxy</span >
36+ <span class =" usecase-card__desc" >SOCKS proxy pela rede remota</span >
37+ </button >
38+ </div >
39+ <div class =" usecase-banner" id =" usecase-banner" hidden >
40+ <span id =" usecase-banner-text" ></span >
41+ <button class =" usecase-banner__close" id =" usecase-banner-close" aria-label =" Fechar" >× </button >
42+ </div >
43+ </section >
44+
2045 <!-- Tunnel Type Selector -->
2146 <section class =" section" >
2247 <div class =" type-selector" id =" type-selector" >
@@ -536,6 +561,62 @@ import Tooltip from '../components/Tooltip.astro';
536561 });
537562 });
538563
564+ // --- Use-case cards ---
565+ const usecaseBanner = $<HTMLElement>('usecase-banner');
566+ const usecaseBannerText = $<HTMLElement>('usecase-banner-text');
567+
568+ const usecases: Record<string, { type: TunnelType; listenPort: number; destHost: string; destPort: number; server: string; user: string; alias: string; banner: string }> = {
569+ 'remote-db': {
570+ type: 'local', listenPort: 5432, destHost: 'db.internal', destPort: 5432,
571+ server: 'bastion.exemplo.com', user: 'deploy', alias: 'db-tunnel',
572+ banner: 'Exemplo carregado — após conectar, use "psql -h localhost -p 5432" para acessar o banco remoto como se fosse local.',
573+ },
574+ 'expose-local': {
575+ type: 'remote', listenPort: 8080, destHost: 'localhost', destPort: 3000,
576+ server: 'servidor.exemplo.com', user: 'deploy', alias: 'expose-dev',
577+ banner: 'Exemplo carregado — seu colega poderá acessar seu app local em servidor.exemplo.com:8080.',
578+ },
579+ 'socks-proxy': {
580+ type: 'dynamic', listenPort: 1080, destHost: '', destPort: 0,
581+ server: 'proxy.exemplo.com', user: 'usuario', alias: 'socks-proxy',
582+ banner: 'Exemplo carregado — configure seu navegador para usar proxy SOCKS5 em localhost:1080.',
583+ },
584+ };
585+
586+ document.querySelectorAll<HTMLButtonElement>('.usecase-card').forEach((card) => {
587+ card.addEventListener('click', () => {
588+ const uc = usecases[card.dataset.usecase!];
589+ if (!uc) return;
590+
591+ // Switch type (this resets fields and updates labels)
592+ switchType(uc.type);
593+ typeBtns.forEach((b) => {
594+ b.classList.toggle('type-btn--active', b.dataset.type === uc.type);
595+ });
596+
597+ // Fill fields
598+ listenPort.value = String(uc.listenPort);
599+ destHost.value = uc.destHost;
600+ destPort.value = String(uc.destPort);
601+ ($<HTMLInputElement>('ssh-server')).value = uc.server;
602+ ($<HTMLInputElement>('ssh-user')).value = uc.user;
603+ ($<HTMLInputElement>('host-alias')).value = uc.alias;
604+
605+ // Show banner
606+ usecaseBannerText.textContent = uc.banner;
607+ usecaseBanner.hidden = false;
608+
609+ update();
610+
611+ // Scroll to form
612+ $<HTMLElement>('tunnel-form').scrollIntoView({ behavior: 'smooth', block: 'start' });
613+ });
614+ });
615+
616+ $<HTMLElement>('usecase-banner-close').addEventListener('click', () => {
617+ usecaseBanner.hidden = true;
618+ });
619+
539620 // Initial render
540621 update();
541622</script >
0 commit comments