Skip to content

Commit

Permalink
(feat:transitions) custom hook to loading state
Browse files Browse the repository at this point in the history
  • Loading branch information
ManishMadan2882 committed Feb 13, 2025
1 parent d08861f commit 181bf69
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 144 deletions.
20 changes: 20 additions & 0 deletions frontend/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,23 @@ export function useDarkTheme() {

return [isDarkTheme, toggleTheme, componentMounted] as const;
}

export function useLoaderState(
initialState = false,
delay = 500,
): [boolean, (value: boolean) => void] {
const [state, setState] = useState<boolean>(initialState);

const setLoaderState = (value: boolean) => {
if (value) {
setState(true);
} else {
// Only add delay when changing from true to false
setTimeout(() => {
setState(false);
}, delay);
}
};

return [state, setLoaderState];
}
148 changes: 63 additions & 85 deletions frontend/src/settings/APIKeys.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback } from 'react';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';

import userService from '../api/services/userService';
Expand All @@ -8,31 +8,22 @@ import SaveAPIKeyModal from '../modals/SaveAPIKeyModal';
import ConfirmationModal from '../modals/ConfirmationModal';
import { APIKeyData } from './types';
import SkeletonLoader from '../components/SkeletonLoader';
import { useLoaderState } from '../hooks';

export default function APIKeys() {
const { t } = useTranslation();
const [isCreateModalOpen, setCreateModal] = useState(false);
const [isSaveKeyModalOpen, setSaveKeyModal] = useState(false);
const [newKey, setNewKey] = useState('');
const [apiKeys, setApiKeys] = useState<APIKeyData[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const [loading, setLoading] = useLoaderState(true);
const [keyToDelete, setKeyToDelete] = useState<{
id: string;
name: string;
} | null>(null);

const setLoadingWithMinDuration = useCallback((isLoading: boolean) => {
if (isLoading) {
setLoading(true);
} else {
setTimeout(() => {
setLoading(false);
}, 2000);
}
}, []);

const handleFetchKeys = useCallback(async () => {
setLoadingWithMinDuration(true);
const handleFetchKeys = async () => {
setLoading(true);
try {
const response = await userService.getAPIKeys();
if (!response.ok) {
Expand All @@ -43,80 +34,67 @@ export default function APIKeys() {
} catch (error) {
console.log(error);
} finally {
setLoadingWithMinDuration(false);
setLoading(false);
}
}, [setLoadingWithMinDuration]);
};

const handleDeleteKey = useCallback(
(id: string) => {
setLoadingWithMinDuration(true);
userService
.deleteAPIKey({ id })
.then((response) => {
if (!response.ok) {
throw new Error('Failed to delete API Key');
}
return response.json();
})
.then((data) => {
if (data.success === true) {
setApiKeys((previous) => previous.filter((elem) => elem.id !== id));
}
setKeyToDelete(null);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
setLoadingWithMinDuration(false);
});
},
[setLoadingWithMinDuration],
);
const handleDeleteKey = (id: string) => {
setLoading(true);
userService
.deleteAPIKey({ id })
.then((response) => {
if (!response.ok) {
throw new Error('Failed to delete API Key');
}
return response.json();
})
.then((data) => {
data.success === true &&
setApiKeys((previous) => previous.filter((elem) => elem.id !== id));
setKeyToDelete(null);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
setLoading(false);
});
};

const handleCreateKey = useCallback(
(payload: {
name: string;
source?: string;
retriever?: string;
prompt_id: string;
chunks: string;
}) => {
setLoadingWithMinDuration(true);
userService
.createAPIKey(payload)
.then((response) => {
if (!response.ok) {
throw new Error('Failed to create API Key');
}
return response.json();
})
.then((data) => {
setApiKeys((prevKeys) => [...prevKeys, data]);
setCreateModal(false);
setNewKey(data.key);
setSaveKeyModal(true);
handleFetchKeys();
})
.catch((error) => {
console.error(error);
})
.finally(() => {
setLoadingWithMinDuration(false);
});
},
[handleFetchKeys, setLoadingWithMinDuration],
);
const handleCreateKey = (payload: {
name: string;
source?: string;
retriever?: string;
prompt_id: string;
chunks: string;
}) => {
setLoading(true);
userService
.createAPIKey(payload)
.then((response) => {
if (!response.ok) {
throw new Error('Failed to create API Key');
}
return response.json();
})
.then((data) => {
setApiKeys([...apiKeys, data]);
setCreateModal(false);
setNewKey(data.key);
setSaveKeyModal(true);
handleFetchKeys();
})
.catch((error) => {
console.error(error);
})
.finally(() => {
setLoading(false);
});
};

useEffect(() => {
React.useEffect(() => {
handleFetchKeys();
}, [handleFetchKeys]);

const confirmDelete = () => {
if (keyToDelete) {
handleDeleteKey(keyToDelete.id);
}
};
}, []);

return (
<div className="mt-8">
Expand Down Expand Up @@ -149,7 +127,7 @@ export default function APIKeys() {
modalState="ACTIVE"
setModalState={() => setKeyToDelete(null)}
submitLabel={t('modals.deleteConv.delete')}
handleSubmit={confirmDelete}
handleSubmit={() => handleDeleteKey(keyToDelete.id)}
handleCancel={() => setKeyToDelete(null)}
/>
)}
Expand Down Expand Up @@ -192,7 +170,7 @@ export default function APIKeys() {
</tr>
)}
{Array.isArray(apiKeys) &&
apiKeys.map((element, index) => (
apiKeys?.map((element, index) => (
<tr
key={index}
className="text-nowrap whitespace-nowrap text-center text-sm font-medium text-gray-800 dark:text-neutral-200 p-2"
Expand Down
34 changes: 8 additions & 26 deletions frontend/src/settings/Analytics.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback } from 'react';
import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import {
BarElement,
Expand All @@ -16,6 +16,7 @@ import Dropdown from '../components/Dropdown';
import { htmlLegendPlugin } from '../utils/chartUtils';
import { formatDate } from '../utils/dateTimeUtils';
import { APIKeyData } from './types';
import { useLoaderState } from '../hooks';

import type { ChartData } from 'chart.js';
import SkeletonLoader from '../components/SkeletonLoader';
Expand Down Expand Up @@ -88,25 +89,9 @@ export default function Analytics() {
value: 'last_30_days',
});

const [loadingMessages, setLoadingMessages] = useState<boolean>(false);
const [loadingTokens, setLoadingTokens] = useState<boolean>(false);
const [loadingFeedback, setLoadingFeedback] = useState<boolean>(false);

const setLoadingWithMinDuration = useCallback(
(
setter: React.Dispatch<React.SetStateAction<boolean>>,
isLoading: boolean,
) => {
if (isLoading) {
setter(true);
} else {
setTimeout(() => {
setter(false);
}, 2000);
}
},
[],
);
const [loadingMessages, setLoadingMessages] = useLoaderState(true);
const [loadingTokens, setLoadingTokens] = useLoaderState(true);
const [loadingFeedback, setLoadingFeedback] = useLoaderState(true);

const fetchChatbots = async () => {
try {
Expand All @@ -133,11 +118,10 @@ export default function Analytics() {
}
const data = await response.json();
setMessagesData(data.messages);
setLoadingWithMinDuration(setLoadingMessages, false);
} catch (error) {
console.error(error);
} finally {
setLoadingWithMinDuration(setLoadingMessages, false);
setLoadingMessages(false);
}
};

Expand All @@ -153,11 +137,10 @@ export default function Analytics() {
}
const data = await response.json();
setTokenUsageData(data.token_usage);
setLoadingWithMinDuration(setLoadingTokens, false);
} catch (error) {
console.error(error);
} finally {
setLoadingWithMinDuration(setLoadingTokens, false);
setLoadingTokens(false);
}
};

Expand All @@ -173,11 +156,10 @@ export default function Analytics() {
}
const data = await response.json();
setFeedbackData(data.feedback);
setLoadingWithMinDuration(setLoadingFeedback, false);
} catch (error) {
console.error(error);
} finally {
setLoadingWithMinDuration(setLoadingFeedback, false);
setLoadingFeedback(false);
}
};

Expand Down
Loading

0 comments on commit 181bf69

Please sign in to comment.