Skip to content

Commit

Permalink
[update(state)][decks]: update deck loading state
Browse files Browse the repository at this point in the history
DESCRIPTION: This commit updates the state management for decks to include a loading state.

ISSUES: Still loading too slowly.
  • Loading branch information
reedoooo committed May 6, 2024
1 parent ebb5619 commit 6758134
Show file tree
Hide file tree
Showing 23 changed files with 534 additions and 263 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package-lock.json
# production
/build
/future-additions
/dev

# misc
.DS_Store
Expand Down
29 changes: 29 additions & 0 deletions src/context/hooks/useDebounce.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useState, useEffect } from 'react';
/**
* useDebounce hook
*
* @param {any} value - The value to be debounced.
* @param {number} delay - The number of milliseconds to delay.
* @returns {any} - The debounced value after the specified delay.
*/
function useDebounce(value, delay) {
// State and setters for debounced value
const [debouncedValue, setDebouncedValue] = useState(value);
const [delayTime, setDelayTime] = useState(delay || 500);

useEffect(() => {
// Update debounced value after the specified delay
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);

// Cleanup function to cancel the timeout if value or delay changes
return () => {
clearTimeout(handler);
};
}, [value, delay]); // Only re-run effect if value or delay changes

return debouncedValue;
}

export default useDebounce;
4 changes: 2 additions & 2 deletions src/context/hooks/useFormSubmission.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useState } from 'react';
import { handleValidation, zodSchemas } from 'data';
import { handleSchemaValidation, zodSchemas } from 'data';

const useFormSubmission = (formHandlers, formKey) => {
const [isSubmitting, setIsSubmitting] = useState(false);
Expand All @@ -9,7 +9,7 @@ const useFormSubmission = (formHandlers, formKey) => {
setIsSubmitting(true);
console.log('[ACTIVE FORM]', formKey);
console.log('[FORM DATA]', formData);
const validationResult = handleValidation(activeSchema, formData);
const validationResult = handleSchemaValidation(activeSchema, formData);
if (!validationResult.success) {
console.error('[INVALID RESULT]', validationResult);
setIsSubmitting(false);
Expand Down
15 changes: 3 additions & 12 deletions src/context/hooks/useRCFormHook.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { formFields, zodSchemas } from 'data';
import { zodSchemas } from 'data';

const useRCFormHook = (schemaKey, initialData) => {
const useRCFormHook = (schemaKey) => {
const schema = zodSchemas[schemaKey];
const defaultValues = Object.keys(schema.shape).reduce((acc, key) => {
const fieldDefinition = schema.shape[key];
Expand All @@ -19,17 +18,9 @@ const useRCFormHook = (schemaKey, initialData) => {

const methods = useForm({
resolver: zodResolver(schema),
defaultValues: !initialData ? defaultValues : null,
defaultValues,
});

// useEffect(() => {
// console.log(
// // `[1] ${schemaKey} SCHEMA REGISTERED: ${schema}`,
// // `[2] FORMSTATE REGISTERED: ${JSON.stringify(methods.formState)}`,
// `[3] VALUES: ${JSON.stringify(methods.getValues())}`
// );
// }, [methods.formState]);

return methods;
};

Expand Down
42 changes: 26 additions & 16 deletions src/context/hooks/useSelectorActions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ function useSelectorActions() {
handleSelectCollection,
selectedDeck,
handleSelectDeck,
fetchDeckById,
} = useManager();
const [time, setTime] = useState('24hr');
const [stat, setStat] = useState('highpoint');
Expand All @@ -25,17 +26,14 @@ function useSelectorActions() {
light: 'light',
dark: 'dark',
};
const handleSelectChange = (e, selectorName, context) => {
console.log(
'SELECTOR VALUES CHANGED',
e.target.value,
selectorName,
context
);
const handleSelectChange = async (e, selectorName, context) => {
console.log('SELECTOR VALUES CHANGED', e, selectorName, context);
const selectedCollectionId = localStorage.getItem('selectedCollectionId');
const selectedDeckId = localStorage.getItem('selectedDeckId');
const selected = localStorage.getItem('selected' + context);
const selectedCollection = JSON.parse(selected);
const selectedDeck = JSON.parse(selected);
// setTags(selectedDeck.tags);
switch (selectorName) {
case 'timeRange':
setTime(e.target.value);
Expand Down Expand Up @@ -94,22 +92,34 @@ function useSelectorActions() {
handleSelectCollection(selectedCollection);
break;
case 'tags':
const newTag = { id: nanoid(), label: e.target.value };
const updatedTags = [...tags, newTag];
console.log('NEW TAG', updatedTags);
const { name, description, color } = selected;
// selectedDeck.tags = updatedTags;
let updatedTags = [...selectedDeck.tags]; // Copy current tags to manipulate
const { name, description, color } = selectedDeck;

if (e.type === 'add') {
const newTag = { id: nanoid(), label: e.target.value };
if (!updatedTags.some((tag) => tag.label === newTag.label)) {
// Check if tag already exists by label
updatedTags.push(newTag); // Add new tag if not present
}
} else if (e.type === 'delete') {
updatedTags = updatedTags.filter(
(tag) => tag.id !== e.target.value.id
); // Remove tag by id
}

// Update tags in state and backend
setTags(updatedTags); // Update local state
updateEntityField(
await updateEntityField(
'decks',
selectedDeckId,
['tags', 'name', 'description', 'color'],
[updatedTags, name, description, color]
); // Persist tags update

handleSelectDeck(selectedDeck);

e.target.value = ''; // Clear the input after adding a tag
const updatedDeck = await fetchDeckById(selectedDeckId);
console.log('UPDATED DECK', updatedDeck);
handleSelectDeck(updatedDeck);
// e.target.value = ''; // Clear the input after adding a tag
break;
case 'deck':
default:
Expand Down
75 changes: 61 additions & 14 deletions src/context/state/useAuthManager.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ function useAuthManager() {
[accessToken, refreshToken, true, authData, authData.userId],
{ path: '/' }
);
handleSetUser(authData); // Adjust according to your implementation
handleSetUser(authData);
navigate('/home');
},
[handleSetUser, navigate]
[addCookies, handleSetUser, navigate]
);

const clearAuthCookies = useCallback(() => {
deleteCookies([
'accessToken',
Expand All @@ -38,17 +37,23 @@ function useAuthManager() {
'authUser',
'isLoggedIn',
]);
localStorage.clear(); // Clear all local storage data
localStorage.clear();
navigate('/login');
}, [navigate, deleteCookies]);

}, [deleteCookies, navigate]);
const decodeAndSetUser = useCallback(
(accessToken) => {
const decoded = jwt_decode(accessToken);
handleSetUser(decoded); // Adjust according to your implementation
handleSetUser(decoded);
},
[handleSetUser]
);
// const decodeAndSetUser = useCallback(
// (accessToken) => {
// const decoded = jwt_decode(accessToken);
// handleSetUser(decoded); // Adjust according to your implementation
// },
// [handleSetUser]
// );

const executeAuthAction = useCallback(
async (endpoint, requestData) => {
Expand Down Expand Up @@ -93,22 +98,57 @@ function useAuthManager() {
},
[executeAuthAction]
);

const logout = useCallback(async () => {
await executeAuthAction('signout', {
userId: authUser.userId,
accessToken: accessToken,
refreshToken: refreshToken,
});
clearAuthCookies();
}, []);
setLoggingOut(true);
handleRemoveUser();
}, [
executeAuthAction,
clearAuthCookies,
handleRemoveUser,
authUser,
accessToken,
refreshToken,
]);

// const logout = useCallback(async () => {
// await executeAuthAction('signout', {
// userId: authUser.userId,
// accessToken: accessToken,
// refreshToken: refreshToken,
// });
// clearAuthCookies();
// }, []);

useEffect(() => {
if (!isLoggedIn || !accessToken) return;
if (accessToken) {
decodeAndSetUser(accessToken);
}
}, []);
// const checkTokenValidity = useCallback(() => {
// console.log('Checking token validity...', { accessToken });
// if (!accessToken) {
// navigate('/login');
// return;
// }
// try {
// const { exp } = jwt_decode(accessToken);
// const isTokenExpired = Date.now() >= exp * 1000;
// if (isTokenExpired) {
// logout();
// setLoggingOut(true);
// handleRemoveUser();
// }
// } catch (error) {
// console.error('Token validation error:', error);
// }
// }, [user.accessToken]);
const checkTokenValidity = useCallback(() => {
console.log('Checking token validity...', { accessToken });
if (!accessToken) {
Expand All @@ -120,18 +160,25 @@ function useAuthManager() {
const isTokenExpired = Date.now() >= exp * 1000;
if (isTokenExpired) {
logout();
setLoggingOut(true);
handleRemoveUser();
}
} catch (error) {
console.error('Token validation error:', error);
}
}, [user.accessToken]);
}, [accessToken, logout, navigate]);
// useEffect(() => {
// if (!isLoggedIn) return;
// checkTokenValidity();
// }, [checkTokenValidity]);
useEffect(() => {
if (!isLoggedIn) return;
checkTokenValidity();
}, [checkTokenValidity]);

decodeAndSetUser(accessToken);
const intervalId = setInterval(() => {
checkTokenValidity();
}, 300000); // 300000 ms = 5 minutes

return () => clearInterval(intervalId); // Clean up the interval on component unmount
}, [isLoggedIn, accessToken, checkTokenValidity, decodeAndSetUser]);
return { login, logout, signup };
}

Expand Down
3 changes: 2 additions & 1 deletion src/context/state/useManager.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,9 @@ const useManager = () => {
const fetchSingleEntity = useCallback(
async (entity, id) => {
try {
const cleanedId = encodeURIComponent(id.replace(/"/g, ''));
const response = await fetchWrapper(
createApiUrl(entity, `get/${id}`),
createApiUrl(entity, `get/${cleanedId}`),
'GET',
null,
`fetch${entity}`.toLocaleUpperCase()
Expand Down
Loading

0 comments on commit 6758134

Please sign in to comment.