From 90f79a7a691943a496f67f01c1e493256070e4de Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 7 Jul 2025 01:44:45 +0000 Subject: (대표님) 변경사항 20250707 10시 43분 - unstaged 변경사항 추가 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hooks/use-file-download.ts | 204 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 hooks/use-file-download.ts (limited to 'hooks/use-file-download.ts') diff --git a/hooks/use-file-download.ts b/hooks/use-file-download.ts new file mode 100644 index 00000000..4b25661e --- /dev/null +++ b/hooks/use-file-download.ts @@ -0,0 +1,204 @@ +// hooks/use-file-download.ts +// 파일 다운로드 상태 관리 훅 + +import { useState, useCallback } from 'react'; +import { downloadFile, type FileDownloadOptions, type FileDownloadResult } from '@/lib/file-download'; + +/** + * 파일 다운로드 상태 + */ +interface FileDownloadState { + isLoading: boolean; + error: string | null; + progress: number; + lastResult: FileDownloadResult | null; +} + +/** + * 단일 파일 다운로드 훅 + */ +export const useFileDownload = () => { + const [state, setState] = useState({ + isLoading: false, + error: null, + progress: 0, + lastResult: null, + }); + + const download = useCallback(async ( + filePath: string, + fileName: string, + options: FileDownloadOptions = {} + ): Promise => { + setState(prev => ({ + ...prev, + isLoading: true, + error: null, + progress: 0, + })); + + const result = await downloadFile(filePath, fileName, { + ...options, + onProgress: (progress) => { + setState(prev => ({ ...prev, progress })); + if (options.onProgress) options.onProgress(progress); + }, + onError: (error) => { + setState(prev => ({ ...prev, error, isLoading: false })); + if (options.onError) options.onError(error); + }, + onSuccess: (fileName, fileSize) => { + setState(prev => ({ + ...prev, + isLoading: false, + error: null, + progress: 100 + })); + if (options.onSuccess) options.onSuccess(fileName, fileSize); + }, + }); + + setState(prev => ({ + ...prev, + isLoading: false, + lastResult: result, + })); + + return result; + }, []); + + const reset = useCallback(() => { + setState({ + isLoading: false, + error: null, + progress: 0, + lastResult: null, + }); + }, []); + + return { + ...state, + download, + reset, + }; +}; + +/** + * 다중 파일 다운로드 훅 + */ +export const useMultiFileDownload = () => { + const [downloads, setDownloads] = useState>(new Map()); + + const getFileState = useCallback((filePath: string): FileDownloadState => { + return downloads.get(filePath) || { + isLoading: false, + error: null, + progress: 0, + lastResult: null, + }; + }, [downloads]); + + const isFileLoading = useCallback((filePath: string): boolean => { + return downloads.get(filePath)?.isLoading || false; + }, [downloads]); + + const getFileError = useCallback((filePath: string): string | null => { + return downloads.get(filePath)?.error || null; + }, [downloads]); + + const updateFileState = useCallback((filePath: string, updates: Partial) => { + setDownloads(prev => { + const newMap = new Map(prev); + const currentState = newMap.get(filePath) || { + isLoading: false, + error: null, + progress: 0, + lastResult: null, + }; + newMap.set(filePath, { ...currentState, ...updates }); + return newMap; + }); + }, []); + + const downloadFile = useCallback(async ( + filePath: string, + fileName: string, + options: FileDownloadOptions = {} + ): Promise => { + updateFileState(filePath, { + isLoading: true, + error: null, + progress: 0, + }); + + const result = await downloadFile(filePath, fileName, { + ...options, + showToast: options.showToast ?? true, + onProgress: (progress) => { + updateFileState(filePath, { progress }); + if (options.onProgress) options.onProgress(progress); + }, + onError: (error) => { + updateFileState(filePath, { error, isLoading: false }); + if (options.onError) options.onError(error); + }, + onSuccess: (fileName, fileSize) => { + updateFileState(filePath, { + isLoading: false, + error: null, + progress: 100 + }); + if (options.onSuccess) options.onSuccess(fileName, fileSize); + }, + }); + + updateFileState(filePath, { + isLoading: false, + lastResult: result, + }); + + return result; + }, [updateFileState]); + + const resetFile = useCallback((filePath: string) => { + setDownloads(prev => { + const newMap = new Map(prev); + newMap.delete(filePath); + return newMap; + }); + }, []); + + const resetAll = useCallback(() => { + setDownloads(new Map()); + }, []); + + return { + downloads, + getFileState, + isFileLoading, + getFileError, + downloadFile, + resetFile, + resetAll, + }; +}; + +/** + * 파일 다운로드 기본 설정 훅 + */ +export const useFileDownloadConfig = (defaultOptions: Partial = {}) => { + const { download, ...state } = useFileDownload(); + + const downloadWithDefaults = useCallback(( + filePath: string, + fileName: string, + options: FileDownloadOptions = {} + ) => { + return download(filePath, fileName, { ...defaultOptions, ...options }); + }, [download, defaultOptions]); + + return { + ...state, + download: downloadWithDefaults, + }; +}; \ No newline at end of file -- cgit v1.2.3