# TanStack Query Hooks Documentation Tất cả các API đã được tách riêng thành TanStack Query hooks trong folder `src/hooks/queries/`. ## Cấu trúc ``` src/hooks/queries/ ├── index.ts # Export tất cả hooks ├── useAuthQueries.ts # Auth hooks ├── useAppVersionQueries.ts # App/Software hooks ├── useDeviceCommQueries.ts # Device communication hooks └── useCommandQueries.ts # Command hooks ``` ## Cách Sử Dụng ### 1. Auth Queries (Xác thực) #### Đăng nhập ```tsx import { useLogin } from '@/hooks/queries' function LoginPage() { const loginMutation = useLogin() const handleLogin = async () => { try { await loginMutation.mutateAsync({ username: 'user', password: 'password' }) // Tự động lưu token vào localStorage } catch (error) { console.error(error) } } return ( ) } ``` #### Đăng xuất ```tsx import { useLogout } from '@/hooks/queries' function LogoutButton() { const logoutMutation = useLogout() return ( ) } ``` #### Kiểm tra phiên ```tsx import { usePing } from '@/hooks/queries' function CheckSession() { const { data, isLoading } = usePing(token, true) if (isLoading) return
Checking...
return
Session: {data?.message}
} ``` #### Thay đổi mật khẩu ```tsx import { useChangePassword } from '@/hooks/queries' function ChangePasswordForm() { const changePasswordMutation = useChangePassword() const handleSubmit = async () => { await changePasswordMutation.mutateAsync({ currentPassword: 'old', newPassword: 'new' }) } return } ``` ### 2. App Version Queries (Phần mềm/Agent) #### Lấy danh sách agent ```tsx import { useGetAgentVersion } from '@/hooks/queries' function AgentList() { const { data: agents, isLoading } = useGetAgentVersion() if (isLoading) return
Loading...
return
{agents?.length} agents
} ``` #### Lấy danh sách phần mềm ```tsx import { useGetSoftwareList } from '@/hooks/queries' function SoftwareList() { const { data: software, isLoading } = useGetSoftwareList() return software?.map(item =>
{item.name}
) } ``` #### Upload file ```tsx import { useUploadSoftware } from '@/hooks/queries' function UploadForm() { const uploadMutation = useUploadSoftware() const handleUpload = async (file: File) => { const formData = new FormData() formData.append('file', file) await uploadMutation.mutateAsync({ formData, onUploadProgress: (event) => { const percent = (event.loaded / event.total) * 100 console.log(`Upload: ${percent}%`) } }) } return e.target.files && handleUpload(e.target.files[0])} /> } ``` #### Quản lý blacklist ```tsx import { useGetBlacklist, useAddBlacklist, useDeleteBlacklist } from '@/hooks/queries' function BlacklistManager() { const { data: blacklist } = useGetBlacklist() const addMutation = useAddBlacklist() const deleteMutation = useDeleteBlacklist() const handleAdd = async () => { await addMutation.mutateAsync({ appId: 1 }) } const handleDelete = async (appId: number) => { await deleteMutation.mutateAsync(appId) } return ( <> {blacklist?.map(item => (
{item.name}
))} ) } ``` ### 3. Device Communication Queries #### Lấy danh sách phòng ```tsx import { useGetRoomList } from '@/hooks/queries' function RoomSelector() { const { data: rooms } = useGetRoomList() return ( ) } ``` #### Lấy thiết bị trong phòng ```tsx import { useGetDeviceFromRoom } from '@/hooks/queries' function DeviceList({ roomName }: { roomName: string }) { const { data: devices, isLoading } = useGetDeviceFromRoom(roomName, true) if (isLoading) return
Loading devices...
return devices?.map(device => (
{device.name}
)) } ``` #### Gửi lệnh ```tsx import { useSendCommand } from '@/hooks/queries' function CommandForm() { const sendMutation = useSendCommand() const handleSend = async () => { await sendMutation.mutateAsync({ roomName: 'Room A', data: { command: 'dir' } }) } return } ``` #### Cài đặt phần mềm ```tsx import { useInstallMsi } from '@/hooks/queries' function InstallSoftware() { const installMutation = useInstallMsi() const handleInstall = async () => { await installMutation.mutateAsync({ roomName: 'Room A', data: { msiFileId: 1 } }) } return } ``` ### 4. Command Queries #### Lấy danh sách lệnh ```tsx import { useGetCommandList } from '@/hooks/queries' function CommandList() { const { data: commands } = useGetCommandList() return commands?.map(cmd =>
{cmd.name}
) } ``` #### Thêm lệnh ```tsx import { useAddCommand } from '@/hooks/queries' function AddCommandForm() { const addMutation = useAddCommand() const handleAdd = async () => { await addMutation.mutateAsync({ name: 'My Command', command: 'echo hello' }) } return } ``` ## Lợi ích 1. **Automatic Caching** - TanStack Query tự động cache dữ liệu 2. **Background Refetching** - Cập nhật dữ liệu trong background 3. **Stale Time Management** - Kiểm soát thời gian dữ liệu còn "fresh" 4. **Automatic Invalidation** - Tự động update dữ liệu sau mutations 5. **Deduplication** - Gộp các request giống nhau 6. **Error Handling** - Xử lý lỗi tập trung 7. **Loading States** - Tracking loading/pending/error states ## Advanced Usage ### Dependent Queries ```tsx function DeviceDetails({ deviceId }: { deviceId: number }) { const { data: device } = useGetDeviceFromRoom(deviceId, true) // Chỉ fetch khi có device const { data: status } = useGetClientFolderStatus( device?.roomName, !!device ) return
{status?.path}
} ``` ### Prefetching ```tsx import { useQueryClient } from '@tanstack/react-query' import { useGetSoftwareList } from '@/hooks/queries' function PrefetchOnHover() { const queryClient = useQueryClient() const handleMouseEnter = () => { queryClient.prefetchQuery({ queryKey: ['app-version', 'software'], queryFn: () => useGetSoftwareList }) } return
Hover me
} ``` ## Migration từ cách cũ **Trước:** ```tsx const { data } = useQueryData({ queryKey: ["software-version"], url: API_ENDPOINTS.APP_VERSION.GET_SOFTWARE, }) ``` **Sau:** ```tsx const { data } = useGetSoftwareList() ``` Đơn giản hơn, type-safe hơn, và dễ bảo trì hơn!