mirror of
https://github.com/johndoe6345789/docker-swarm-termina.git
synced 2026-04-24 13:45:01 +00:00
Refactor components to use custom hooks
- Extract login form logic into useLoginForm hook - Create useAuthRedirect hook for auth-based navigation - Refactor LoginForm component to use useLoginForm (147 -> 135 LOC) - Refactor login page to use useAuthRedirect (23 -> 14 LOC) - Update dashboard to use useAuthRedirect for cleaner code - Improve code reusability and testability https://claude.ai/code/session_01U3wVqokhrL3dTeq2dTq73n
This commit is contained in:
@@ -16,14 +16,15 @@ import {
|
||||
useTheme,
|
||||
} from '@mui/material';
|
||||
import { Logout, Refresh, Inventory2 } from '@mui/icons-material';
|
||||
import { useAppDispatch, useAppSelector } from '@/lib/store/hooks';
|
||||
import { useAppDispatch } from '@/lib/store/hooks';
|
||||
import { logout as logoutAction } from '@/lib/store/authSlice';
|
||||
import { useAuthRedirect } from '@/lib/hooks/useAuthRedirect';
|
||||
import { apiClient, Container as ContainerType } from '@/lib/api';
|
||||
import ContainerCard from '@/components/ContainerCard';
|
||||
import TerminalModal from '@/components/TerminalModal';
|
||||
|
||||
export default function Dashboard() {
|
||||
const { isAuthenticated, loading: authLoading } = useAppSelector((state) => state.auth);
|
||||
const { isAuthenticated, loading: authLoading } = useAuthRedirect('/');
|
||||
const dispatch = useAppDispatch();
|
||||
const router = useRouter();
|
||||
const theme = useTheme();
|
||||
@@ -35,12 +36,6 @@ export default function Dashboard() {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (!authLoading && !isAuthenticated) {
|
||||
router.push('/');
|
||||
}
|
||||
}, [isAuthenticated, authLoading, router]);
|
||||
|
||||
const fetchContainers = async () => {
|
||||
setIsRefreshing(true);
|
||||
setError('');
|
||||
|
||||
@@ -1,19 +1,10 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useAppSelector } from '@/lib/store/hooks';
|
||||
import { useAuthRedirect } from '@/lib/hooks/useAuthRedirect';
|
||||
import LoginForm from '@/components/LoginForm';
|
||||
|
||||
export default function Home() {
|
||||
const { isAuthenticated, loading } = useAppSelector((state) => state.auth);
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (!loading && isAuthenticated) {
|
||||
router.push('/dashboard');
|
||||
}
|
||||
}, [isAuthenticated, loading, router]);
|
||||
const { loading } = useAuthRedirect('/dashboard');
|
||||
|
||||
if (loading) {
|
||||
return null;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import React from 'react';
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
@@ -11,31 +11,19 @@ import {
|
||||
Alert,
|
||||
} from '@mui/material';
|
||||
import { LockOpen } from '@mui/icons-material';
|
||||
import { useAppDispatch, useAppSelector } from '@/lib/store/hooks';
|
||||
import { login, clearError } from '@/lib/store/authSlice';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useLoginForm } from '@/lib/hooks/useLoginForm';
|
||||
|
||||
export default function LoginForm() {
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [isShaking, setIsShaking] = useState(false);
|
||||
const dispatch = useAppDispatch();
|
||||
const { error, loading } = useAppSelector((state) => state.auth);
|
||||
const router = useRouter();
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
dispatch(clearError());
|
||||
|
||||
const result = await dispatch(login({ username, password }));
|
||||
|
||||
if (login.fulfilled.match(result)) {
|
||||
router.push('/dashboard');
|
||||
} else {
|
||||
setIsShaking(true);
|
||||
setTimeout(() => setIsShaking(false), 500);
|
||||
}
|
||||
};
|
||||
const {
|
||||
username,
|
||||
setUsername,
|
||||
password,
|
||||
setPassword,
|
||||
isShaking,
|
||||
error,
|
||||
loading,
|
||||
handleSubmit,
|
||||
} = useLoginForm();
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
||||
20
frontend/lib/hooks/useAuthRedirect.ts
Normal file
20
frontend/lib/hooks/useAuthRedirect.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useAppSelector } from '@/lib/store/hooks';
|
||||
|
||||
export function useAuthRedirect(redirectTo: '/dashboard' | '/') {
|
||||
const { isAuthenticated, loading } = useAppSelector((state) => state.auth);
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) return;
|
||||
|
||||
if (redirectTo === '/dashboard' && isAuthenticated) {
|
||||
router.push('/dashboard');
|
||||
} else if (redirectTo === '/' && !isAuthenticated) {
|
||||
router.push('/');
|
||||
}
|
||||
}, [isAuthenticated, loading, router, redirectTo]);
|
||||
|
||||
return { isAuthenticated, loading };
|
||||
}
|
||||
38
frontend/lib/hooks/useLoginForm.ts
Normal file
38
frontend/lib/hooks/useLoginForm.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useAppDispatch, useAppSelector } from '@/lib/store/hooks';
|
||||
import { login, clearError } from '@/lib/store/authSlice';
|
||||
|
||||
export function useLoginForm() {
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [isShaking, setIsShaking] = useState(false);
|
||||
const dispatch = useAppDispatch();
|
||||
const { error, loading } = useAppSelector((state) => state.auth);
|
||||
const router = useRouter();
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
dispatch(clearError());
|
||||
|
||||
const result = await dispatch(login({ username, password }));
|
||||
|
||||
if (login.fulfilled.match(result)) {
|
||||
router.push('/dashboard');
|
||||
} else {
|
||||
setIsShaking(true);
|
||||
setTimeout(() => setIsShaking(false), 500);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
username,
|
||||
setUsername,
|
||||
password,
|
||||
setPassword,
|
||||
isShaking,
|
||||
error,
|
||||
loading,
|
||||
handleSubmit,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user