From 7c7a966a4aa268778b2e0ffd51f1be63ff458bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=95=9C=EB=8F=99=ED=98=84?= <hando1220@ajou.ac.kr> Date: Fri, 14 Mar 2025 19:48:05 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=8F=AC=ED=8A=B8=ED=8F=AC=EC=9B=8C?= =?UTF-8?q?=EB=94=A9=20=EB=AA=A9=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/forwarding/List.tsx | 165 +++++++++++++++++++--------------- src/types/forwarding.ts | 9 ++ 2 files changed, 102 insertions(+), 72 deletions(-) create mode 100644 src/types/forwarding.ts diff --git a/src/pages/forwarding/List.tsx b/src/pages/forwarding/List.tsx index 30dcb86..c9392c2 100644 --- a/src/pages/forwarding/List.tsx +++ b/src/pages/forwarding/List.tsx @@ -1,53 +1,47 @@ +import { useEffect, useState } from 'react'; +import { Link } from 'react-router'; import { Filter, Plus, Pencil, Trash } from 'lucide-react'; +import { toast } from 'sonner'; +import { useAuthStore } from '@/stores/authStore'; import { Button } from '@/components/ui/button'; import { Card, CardContent } from '@/components/ui/card'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card'; import { Input } from '@/components/ui/input'; -import { Link } from 'react-router'; - -const forwardings = [ - { - id: 1, - name: '아올다 프록시 매니저 콘솔', - created_at: '2021-09-01 11:43:00', - updated_at: '2021-09-01 12:00:00', - port: 20444, - instance_ip: '10.16.0.10', - }, - { - id: 2, - name: '아올다 블로그', - created_at: '2021-09-01 12:00:00', - updated_at: '2021-09-01 12:01:00', - port: 22222, - instance_ip: '10.16.0.11', - }, - { - id: 3, - name: '개인 블로그', - created_at: '2021-09-01 12:01:00', - updated_at: '2021-09-01 13:00:00', - port: 20411, - instance_ip: '10.16.3.23', - }, - { - id: 4, - name: '아올다 테스트 서버', - created_at: '2021-09-01 13:00:00', - updated_at: '2021-09-02 12:00:00', - port: 20432, - instance_ip: '10.16.32.1', - }, -]; +import { Forwarding } from '@/types/forwarding'; +import { Skeleton } from '@/components/ui/skeleton'; export default function ForwardingList() { + const { selectedProject } = useAuthStore(); + const [forwardings, setForwardings] = useState<Forwarding[] | null>(null); + + useEffect(() => { + fetch(`/api/forwardings?projectId=${selectedProject?.id}`) + .then((response) => { + if (!response.ok) { + toast.error('포트포워딩 정보를 조회할 수 없습니다.'); + return { forwardings: [] }; + } + + return response.json(); + }) + .then(({ contents }) => { + setForwardings(contents); + }); + }, [selectedProject]); + return ( <div className="flex flex-1 flex-col gap-4 p-6"> <div className="flex justify-between mb-2"> <div> <h1 className="scroll-m-20 text-3xl font-semibold first:mt-0">SSH 포트포워딩 설정</h1> - <p className="mt-1 text-base text-gray-500">현재 4개의 SSH 포트포워딩이 설정되어 있습니다.</p> + {forwardings === null ? ( + <Skeleton className="w-[24rem] h-[1rem] mt-2 rounded-full" /> + ) : ( + <p className="mt-1 text-base text-gray-500"> + 현재 {forwardings?.length}개의 SSH 포트포워딩이 설정되어 있습니다. + </p> + )} </div> <Button className="ml-2" asChild> <Link to="./create"> @@ -72,43 +66,70 @@ export default function ForwardingList() { </TableRow> </TableHeader> <TableBody> - {forwardings.map((forwarding) => ( - <TableRow key={forwarding.id}> - <TableCell className="truncate max-w-48"> - <HoverCard> - <HoverCardTrigger>{forwarding.name}</HoverCardTrigger> - <HoverCardContent className="w-80 whitespace-normal"> - <div className="flex justify-between space-x-4"> - <div className="space-y-1"> - <p className="text-sm font-semibold">{forwarding.name}</p> - <p className="text-sm"> - ssh.aoldacloud.com:{forwarding.port} ↔ {forwarding.instance_ip}:22 - </p> - <p className="text-xs text-muted-foreground mt-2">{forwarding.created_at} 생성</p> - <p className="text-xs text-muted-foreground">{forwarding.updated_at} 수정</p> - </div> - </div> - </HoverCardContent> - </HoverCard> - </TableCell> - <TableCell>{forwarding.port}</TableCell> - <TableCell>{forwarding.instance_ip}</TableCell> - <TableCell> - <div className="flex justify-center items-center gap-2"> - <Button variant="secondary" className="size-8"> - <Link to={`./edit/${forwarding.id}`}> - <Pencil /> - </Link> - </Button> - <Button variant="secondary" className="size-8"> - <Link to={`./delete/${forwarding.id}`}> - <Trash /> - </Link> - </Button> - </div> + {forwardings === null ? ( + <> + <TableRow> + <TableCell colSpan={4}> + <Skeleton className="w-full h-[1rem] my-2 rounded-full" /> + </TableCell> + </TableRow> + <TableRow> + <TableCell colSpan={4}> + <Skeleton className="w-full h-[1rem] my-2 rounded-full" /> + </TableCell> + </TableRow> + <TableRow> + <TableCell colSpan={4}> + <Skeleton className="w-full h-[1rem] my-2 rounded-full" /> + </TableCell> + </TableRow> + </> + ) : forwardings.length === 0 ? ( + <TableRow> + <TableCell colSpan={4} className="text-center text-muted-foreground"> + 현재 프로젝트에 등록된 포트포워딩 설정이 없습니다. </TableCell> </TableRow> - ))} + ) : ( + forwardings.map((forwarding) => ( + <TableRow key={forwarding.id}> + <TableCell className="truncate max-w-48"> + <HoverCard> + <HoverCardTrigger>{forwarding.name}</HoverCardTrigger> + <HoverCardContent className="w-80 whitespace-normal"> + <div className="flex justify-between space-x-4"> + <div className="space-y-1"> + <p className="text-sm font-semibold">{forwarding.name}</p> + <p className="text-sm"> + ssh.aoldacloud.com:{forwarding.serverPort} ↔ {forwarding.instanceIp}: + {forwarding.instancePort} + </p> + <p className="text-xs text-muted-foreground mt-2">{forwarding.createdAt} 생성</p> + <p className="text-xs text-muted-foreground">{forwarding.updatedAt} 수정</p> + </div> + </div> + </HoverCardContent> + </HoverCard> + </TableCell> + <TableCell>{forwarding.serverPort}</TableCell> + <TableCell>{forwarding.instanceIp}</TableCell> + <TableCell> + <div className="flex justify-center items-center gap-2"> + <Button variant="secondary" className="size-8"> + <Link to={`./edit/${forwarding.id}`}> + <Pencil /> + </Link> + </Button> + <Button variant="secondary" className="size-8"> + <Link to={`./delete/${forwarding.id}`}> + <Trash /> + </Link> + </Button> + </div> + </TableCell> + </TableRow> + )) + )} </TableBody> </Table> </CardContent> diff --git a/src/types/forwarding.ts b/src/types/forwarding.ts new file mode 100644 index 0000000..4acaa5e --- /dev/null +++ b/src/types/forwarding.ts @@ -0,0 +1,9 @@ +export interface Forwarding { + id: number; + name: string; + createdAt: string; + updatedAt: string; + serverPort: number; + instanceIp: string; + instancePort: number; +} -- GitLab