From 6574d9cc84476f375c81000f5064e204e93f0f4e Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Sat, 20 Sep 2025 00:04:27 +0530 Subject: [PATCH] (feat:pickers) ux, code refactor --- frontend/src/components/FilePicker.tsx | 352 +++++++++--------- frontend/src/components/GoogleDrivePicker.tsx | 235 +++++++----- frontend/src/upload/Upload.tsx | 2 - 3 files changed, 302 insertions(+), 287 deletions(-) diff --git a/frontend/src/components/FilePicker.tsx b/frontend/src/components/FilePicker.tsx index fb27b5c3..68f012bc 100644 --- a/frontend/src/components/FilePicker.tsx +++ b/frontend/src/components/FilePicker.tsx @@ -286,204 +286,184 @@ export const FilePicker: React.FC = ({ } }; - // Render authentication UI - if (!isConnected) { - return ( -
- {authError && ( -
{authError}
- )} - { - setUserEmail(data.user_email || 'Connected User'); - setIsConnected(true); - setAuthError(''); - - if (data.session_token) { - setSessionToken(provider, data.session_token); - loadCloudFiles(data.session_token, null); - } - }} - onError={(error) => { - setAuthError(error); - setIsConnected(false); - }} - /> -
- ); - } - - // Render file browser UI return (
- {/* Connected state indicator */} -
-
-
- - - - Connected as {userEmail} -
- -
-
+ removeSessionToken(provider); + setIsConnected(false); + setFiles([]); + setSelectedFiles([]); + onSelectionChange([]); -
-
- {/* Breadcrumb navigation */} -
-
- {folderPath.map((path, index) => ( -
- {index > 0 && /} - -
- ))} + if (onDisconnect) { + onDisconnect(); + } + }} + /> + + {isConnected && ( +
+
+ {/* Breadcrumb navigation */} +
+
+ {folderPath.map((path, index) => ( +
+ {index > 0 && /} + +
+ ))} +
+ +
+ Select Files from {getProviderConfig(provider).displayName} +
+ +
+ handleSearchChange(e.target.value)} + colorVariant="silver" + borderVariant="thin" + labelBgClassName="bg-[#EEE6FF78] dark:bg-[#2A262E]" + leftIcon={Search} + /> +
+ + {/* Selected Files Message */} +
+ {selectedFiles.length + selectedFolders.length} selected +
-
- Select Files from {getProviderConfig(provider).displayName} -
- -
- handleSearchChange(e.target.value)} - colorVariant="silver" - borderVariant="thin" - labelBgClassName="bg-[#EEE6FF78] dark:bg-[#2A262E]" - leftIcon={Search} - /> -
- - {/* Selected Files Message */} -
- {selectedFiles.length + selectedFolders.length} selected -
-
- -
- - {( - <> - - - - - Name - Last Modified - Size - - - - {files.map((file, index) => ( - { - if (isFolder(file)) { - handleFolderClick(file.id, file.name); - } else { - handleFileSelect(file.id, false); - } - }} - > - -
{ - e.stopPropagation(); - handleFileSelect(file.id, isFolder(file)); - }} - > - {(isFolder(file) ? selectedFolders : selectedFiles).includes(file.id) && ( - Selected - )} -
-
- -
-
- {isFolder(file) -
- {file.name} -
-
- - {formatDate(file.modifiedTime)} - - - {file.size ? formatBytes(file.size) : '-'} - +
+ + {( + <> +
+ + + + Name + Last Modified + Size - ))} - -
+ + + {files.map((file, index) => ( + { + if (isFolder(file)) { + handleFolderClick(file.id, file.name); + } else { + handleFileSelect(file.id, false); + } + }} + > + +
{ + e.stopPropagation(); + handleFileSelect(file.id, isFolder(file)); + }} + > + {(isFolder(file) ? selectedFolders : selectedFiles).includes(file.id) && ( + Selected + )} +
+
+ +
+
+ {isFolder(file) +
+ {file.name} +
+
+ + {formatDate(file.modifiedTime)} + + + {file.size ? formatBytes(file.size) : '-'} + +
+ ))} +
+ - {isLoading && ( -
-
-
- Loading more files... + {isLoading && ( +
+
+
+ Loading more files... +
-
- )} - - )} - + )} + + )} + +
-
+ )}
); }; diff --git a/frontend/src/components/GoogleDrivePicker.tsx b/frontend/src/components/GoogleDrivePicker.tsx index 57d27d60..b2046b87 100644 --- a/frontend/src/components/GoogleDrivePicker.tsx +++ b/frontend/src/components/GoogleDrivePicker.tsx @@ -17,15 +17,11 @@ interface PickerFile { interface GoogleDrivePickerProps { token: string | null; onSelectionChange: (fileIds: string[], folderIds?: string[]) => void; - initialSelectedFiles?: string[]; - initialSelectedFolders?: string[]; } const GoogleDrivePicker: React.FC = ({ token, onSelectionChange, - initialSelectedFiles = [], - initialSelectedFolders = [], }) => { const [selectedFiles, setSelectedFiles] = useState([]); const [selectedFolders, setSelectedFolders] = useState([]); @@ -34,12 +30,15 @@ const GoogleDrivePicker: React.FC = ({ const [isConnected, setIsConnected] = useState(false); const [authError, setAuthError] = useState(''); const [accessToken, setAccessToken] = useState(null); + const [isValidating, setIsValidating] = useState(false); const [openPicker] = useDrivePicker(); useEffect(() => { const sessionToken = getSessionToken('google_drive'); if (sessionToken) { + setIsValidating(true); + setIsConnected(true); // Optimistically set as connected for skeleton validateSession(sessionToken); } }, [token]); @@ -59,6 +58,7 @@ const GoogleDrivePicker: React.FC = ({ if (!validateResponse.ok) { setIsConnected(false); setAuthError('Session expired. Please reconnect to Google Drive.'); + setIsValidating(false); return false; } @@ -68,16 +68,19 @@ const GoogleDrivePicker: React.FC = ({ setIsConnected(true); setAuthError(''); setAccessToken(validateData.access_token || null); + setIsValidating(false); return true; } else { setIsConnected(false); setAuthError(validateData.error || 'Session expired. Please reconnect your account.'); + setIsValidating(false); return false; } } catch (error) { console.error('Error validating session:', error); setAuthError('Failed to validate session. Please reconnect.'); setIsConnected(false); + setIsValidating(false); return false; } }; @@ -100,17 +103,15 @@ const GoogleDrivePicker: React.FC = ({ } try { - const clientId = import.meta.env.VITE_GOOGLE_CLIENT_ID; - const developerKey = import.meta.env.VITE_GOOGLE_API_KEY; - const appId = import.meta.env.VITE_GOOGLE_DRIVE_APP_ID; + const clientId: string = import.meta.env.VITE_GOOGLE_CLIENT_ID; + const developerKey : string = import.meta.env.VITE_GOOGLE_API_KEY; + + // Derive appId from clientId (extract numeric part before first dash) + const appId = clientId ? clientId.split('-')[0] : null; if (!clientId || !developerKey || !appId) { - console.error('Missing Google Drive configuration:', { - clientId: !!clientId, - developerKey: !!developerKey, - appId: !!appId - }); - setAuthError('Google Drive configuration is incomplete. Please check your environment variables.'); + console.error('Missing Google Drive configuration'); + setIsLoading(false); return; } @@ -194,110 +195,146 @@ const GoogleDrivePicker: React.FC = ({ console.error('Error disconnecting from Google Drive:', err); } } - + removeSessionToken('google_drive'); setIsConnected(false); setSelectedFiles([]); setSelectedFolders([]); + setAccessToken(null); + setUserEmail(''); + setAuthError(''); onSelectionChange([], []); }; + const ConnectedStateSkeleton = () => ( +
+
+
+
+
+
+
+
+
+ ); + + const FilesSectionSkeleton = () => ( +
+
+
+
+
+
+
+
+
+ ); + return (
- { - setUserEmail(data.user_email || 'Connected User'); - setIsConnected(true); - setAuthError(''); + {isValidating ? ( + <> + + + + ) : ( + <> + { + setUserEmail(data.user_email || 'Connected User'); + setIsConnected(true); + setAuthError(''); - if (data.session_token) { - setSessionToken('google_drive', data.session_token); - validateSession(data.session_token); - } - }} - onError={(error) => { - setAuthError(error); - setIsConnected(false); - }} - isConnected={isConnected} - userEmail={userEmail} - onDisconnect={handleDisconnect} - errorMessage={authError} - /> + if (data.session_token) { + setSessionToken('google_drive', data.session_token); + validateSession(data.session_token); + } + }} + onError={(error) => { + setAuthError(error); + setIsConnected(false); + }} + isConnected={isConnected} + userEmail={userEmail} + onDisconnect={handleDisconnect} + errorMessage={authError} + /> - {isConnected && ( -
-
-
-

Selected Files

- -
+ {isConnected && ( +
+
+
+

Selected Files

+ +
- {selectedFiles.length === 0 && selectedFolders.length === 0 ? ( -

No files or folders selected

- ) : ( -
- {selectedFolders.length > 0 && ( -
-

Folders

- {selectedFolders.map((folder) => ( -
- Folder - {folder.name} - + {selectedFiles.length === 0 && selectedFolders.length === 0 ? ( +

No files or folders selected

+ ) : ( +
+ {selectedFolders.length > 0 && ( +
+

Folders

+ {selectedFolders.map((folder) => ( +
+ Folder + {folder.name} + +
+ ))}
- ))} -
- )} + )} - {selectedFiles.length > 0 && ( -
-

Files

- {selectedFiles.map((file) => ( -
- File - {file.name} - + {selectedFiles.length > 0 && ( +
+

Files

+ {selectedFiles.map((file) => ( +
+ File + {file.name} + +
+ ))}
- ))} + )}
)}
- )} -
-
+
+ )} + )}
); diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index e51f14f8..174a22d6 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -241,8 +241,6 @@ function Upload({ setSelectedFolders(selectedFolderIds); }} token={token} - initialSelectedFiles={selectedFiles} - initialSelectedFolders={selectedFolders} /> ); default: