From ccad23bf97535cea5da5876a0e375e9ed8d04d92 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: Thu, 8 May 2025 00:06:23 +0900
Subject: [PATCH] =?UTF-8?q?feat:=20API=20=EC=9D=91=EB=8B=B5=20=EB=8C=80?=
 =?UTF-8?q?=EA=B8=B0=EC=A4=91=20=EB=B2=84=ED=8A=BC=20=EB=A1=9C=EB=94=A9=20?=
 =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/components/login-form.tsx   | 9 ++++++++-
 src/pages/forwarding/Create.tsx | 6 +++++-
 src/pages/forwarding/Edit.tsx   | 6 +++++-
 src/pages/routing/Create.tsx    | 7 +++++--
 src/pages/routing/Edit.tsx      | 9 ++++++---
 5 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/src/components/login-form.tsx b/src/components/login-form.tsx
index 104389e..095c6d1 100644
--- a/src/components/login-form.tsx
+++ b/src/components/login-form.tsx
@@ -1,5 +1,6 @@
 import React from 'react';
 import { useNavigate } from 'react-router';
+import { LoaderCircle } from 'lucide-react';
 import { cn } from '@/lib/utils';
 import { useAuthStore } from '@/stores/authStore';
 import { toast } from 'sonner';
@@ -11,9 +12,12 @@ import { Label } from '@/components/ui/label';
 export function LoginForm({ className, ...props }: React.ComponentPropsWithoutRef<'div'>) {
   const { login } = useAuthStore();
   const navigate = useNavigate();
+  const [isLoading, setIsLoading] = React.useState(false);
 
   const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
     e.preventDefault();
+    setIsLoading(true);
+
     const formData = new FormData(e.currentTarget);
     const username = formData.get('username') as string;
     const password = formData.get('password') as string;
@@ -25,6 +29,8 @@ export function LoginForm({ className, ...props }: React.ComponentPropsWithoutRe
       console.error(err);
       toast.error('로그인에 실패했습니다');
     }
+
+    setIsLoading(false);
   };
 
   return (
@@ -45,7 +51,8 @@ export function LoginForm({ className, ...props }: React.ComponentPropsWithoutRe
                 <Label htmlFor="password">비밀번호</Label>
                 <Input id="password" name="password" type="password" placeholder="비밀번호" required />
               </div>
-              <Button type="submit" className="w-full">
+              <Button type="submit" className="w-full" disabled={isLoading}>
+                {isLoading && <LoaderCircle className="animate-spin" />}
                 로그인
               </Button>
             </div>
diff --git a/src/pages/forwarding/Create.tsx b/src/pages/forwarding/Create.tsx
index 7c44fcb..c6d1e05 100644
--- a/src/pages/forwarding/Create.tsx
+++ b/src/pages/forwarding/Create.tsx
@@ -2,6 +2,7 @@ import { z } from 'zod';
 import { zodResolver } from '@hookform/resolvers/zod';
 import { Link, useNavigate } from 'react-router';
 import { useForm } from 'react-hook-form';
+import { LoaderCircle } from 'lucide-react';
 import { Button } from '@/components/ui/button';
 import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
 import { Input } from '@/components/ui/input';
@@ -145,7 +146,10 @@ export default function ForwardingCreate() {
             <Button variant="outline" asChild>
               <Link to="..">취소</Link>
             </Button>
-            <Button type="submit">저장</Button>
+            <Button type="submit" disabled={form.formState.isSubmitting}>
+              {form.formState.isSubmitting && <LoaderCircle className="animate-spin" />}
+              저장
+            </Button>
           </div>
         </form>
       </Form>
diff --git a/src/pages/forwarding/Edit.tsx b/src/pages/forwarding/Edit.tsx
index 265ebf6..c15dc94 100644
--- a/src/pages/forwarding/Edit.tsx
+++ b/src/pages/forwarding/Edit.tsx
@@ -4,6 +4,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
 import { Link, useNavigate, useParams } from 'react-router';
 import { useForm } from 'react-hook-form';
 import { toast } from 'sonner';
+import { LoaderCircle } from 'lucide-react';
 import { Skeleton } from '@/components/ui/skeleton';
 import { Button } from '@/components/ui/button';
 import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
@@ -169,7 +170,10 @@ export default function ForwardingEdit() {
             <Button variant="outline" asChild>
               <Link to="..">취소</Link>
             </Button>
-            <Button type="submit">저장</Button>
+            <Button type="submit" disabled={form.formState.isSubmitting}>
+              {form.formState.isSubmitting && <LoaderCircle className="animate-spin" />}
+              저장
+            </Button>
           </div>
         </form>
       </Form>
diff --git a/src/pages/routing/Create.tsx b/src/pages/routing/Create.tsx
index 44150f9..5934b08 100644
--- a/src/pages/routing/Create.tsx
+++ b/src/pages/routing/Create.tsx
@@ -1,7 +1,7 @@
 import { useEffect, useState } from 'react';
 import { Link, useNavigate } from 'react-router';
 import { useForm, useWatch } from 'react-hook-form';
-import { Check, X } from 'lucide-react';
+import { Check, LoaderCircle, X } from 'lucide-react';
 import { z } from 'zod';
 import { zodResolver } from '@hookform/resolvers/zod';
 import { toast } from 'sonner';
@@ -286,7 +286,10 @@ export default function RoutingCreate() {
             <Button variant="outline" asChild>
               <Link to="..">취소</Link>
             </Button>
-            <Button type="submit">저장</Button>
+            <Button type="submit" disabled={form.formState.isSubmitting}>
+              {form.formState.isSubmitting && <LoaderCircle className="animate-spin" />}
+              저장
+            </Button>
           </div>
         </form>
       </Form>
diff --git a/src/pages/routing/Edit.tsx b/src/pages/routing/Edit.tsx
index 6516936..108b6d8 100644
--- a/src/pages/routing/Edit.tsx
+++ b/src/pages/routing/Edit.tsx
@@ -1,7 +1,7 @@
 import { useEffect, useRef, useState } from 'react';
 import { Link, useNavigate, useParams } from 'react-router';
 import { useForm, useWatch } from 'react-hook-form';
-import { Check, X } from 'lucide-react';
+import { Check, LoaderCircle, X } from 'lucide-react';
 import { z } from 'zod';
 import { zodResolver } from '@hookform/resolvers/zod';
 import { toast } from 'sonner';
@@ -107,7 +107,7 @@ export default function RoutingEdit() {
         console.error(error);
         toast.error('라우팅 설정 정보를 조회할 수 없습니다.');
       });
-  }, []);
+  }, [id]);
 
   useEffect(() => {
     if (enableSSL) {
@@ -346,7 +346,10 @@ export default function RoutingEdit() {
             <Button variant="outline" asChild>
               <Link to="..">취소</Link>
             </Button>
-            <Button type="submit">저장</Button>
+            <Button type="submit" disabled={form.formState.isSubmitting}>
+              {form.formState.isSubmitting && <LoaderCircle className="animate-spin" />}
+              저장
+            </Button>
           </div>
         </form>
       </Form>
-- 
GitLab