| import { z } from "zod"; |
| import { accessSchema, useEnv } from "./lib/state"; |
| import { Copy, Globe, Terminal, Network, Database, Check } from "lucide-react"; |
| import { Button } from "./components/ui/button"; |
| import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./components/ui/tooltip"; |
| import { useCallback, useState } from "react"; |
| |
| export function Gateways() { |
| const env = useEnv(); |
| const groupedAccess = env.access.reduce((acc, curr) => { |
| if (!acc.has(curr.name)) { |
| acc.set(curr.name, []); |
| } |
| acc.get(curr.name)!.push(curr); |
| return acc; |
| }, new Map<string, typeof env.access>()); |
| return ( |
| <ul> |
| {Array.from(groupedAccess.entries()).map(([name, access]) => ( |
| <li key={name}> |
| {access.map((a) => ( |
| <Gateway g={a} /> |
| ))} |
| </li> |
| ))} |
| </ul> |
| ); |
| } |
| |
| function Gateway({ g }: { g: z.infer<typeof accessSchema> }) { |
| const [hidden, content] = (() => { |
| switch (g.type) { |
| case "https": |
| return [g.address, g.address]; |
| case "ssh": |
| case "tcp": |
| case "udp": |
| return [`${g.host}:${g.port}`, `${g.host}:${g.port}`]; |
| case "postgresql": |
| return [ |
| `postgresql://${g.username}:*****@${g.host}:${g.port}/${g.database}`, |
| `postgresql://${g.username}:${g.password}@${g.host}:${g.port}/${g.database}`, |
| ]; |
| case "mongodb": |
| return [ |
| `mongodb://${g.username}:*****@${g.host}:${g.port}/${g.database}`, |
| `mongodb://${g.username}:${g.password}@${g.host}:${g.port}/${g.database}`, |
| ]; |
| } |
| })(); |
| const [clicked, setClicked] = useState(false); |
| const [open, setOpen] = useState(false); |
| const copy = useCallback(() => { |
| navigator.clipboard.writeText(content); |
| setClicked(true); |
| setOpen(true); |
| setTimeout(() => { |
| setClicked(false); |
| setOpen(false); |
| }, 1000); |
| }, [content, setClicked, setOpen]); |
| return ( |
| <TooltipProvider> |
| <Tooltip delayDuration={100} open={open} onOpenChange={setOpen}> |
| <TooltipTrigger asChild> |
| <Button variant="ghost" onClick={copy}> |
| <AccessType type={g.type} className="w-4 h-4" /> |
| <div className="hover:bg-gray-200 p-x-1">{hidden}</div> |
| </Button> |
| </TooltipTrigger> |
| <TooltipContent side="right" className="!bg-transparent cursor-pointer !p-0" sideOffset={1}> |
| {!clicked && <Copy className="w-4 h-4 !bg-transparent" color="black" />} |
| {clicked && <Check className="w-4 h-4 !bg-transparent" color="black" />} |
| </TooltipContent> |
| </Tooltip> |
| </TooltipProvider> |
| ); |
| } |
| |
| function AccessType({ type, className }: { type: z.infer<typeof accessSchema>["type"]; className?: string }) { |
| switch (type) { |
| case "https": |
| return <Globe className={className} />; |
| case "ssh": |
| return <Terminal className={className} />; |
| case "tcp": |
| case "udp": |
| return <Network className={className} />; |
| case "postgresql": |
| case "mongodb": |
| return <Database className={className} />; |
| } |
| } |