-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(login): add hook for login + interceptor #22
base: master
Are you sure you want to change the base?
Conversation
src/App.tsx
Outdated
import Ipfs from "./ipfs/Ipfs"; | ||
function App(): JSX.Element { | ||
// Handle user state | ||
// Ask if we should have this instead directly in a utils instead |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NiiCoder should we extract this to a util ? I wasn't sure as it's using some state ( not sure about how this would be structured)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to have this in utils
</Switch> | ||
</BaseLayout> | ||
</Router> | ||
<UserContext.Provider value={{ isLoggedIn, login, logout }}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought this would be the best to handle the user state. Open to suggestions, if there is a better way to do it with React
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think saving user information in localStorage is not a safe way. We have to ask the user to save user info("Remember me" checkbox).
And for the states that need to be used in several places, prefer to use redux.
<BaseLayout> | ||
<Switch> | ||
<Route path="/login" component={Login} /> | ||
<ProtectedRoute path="/ipfs/:hash" component={Ipfs} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if we couldn't just handle this at a higher level, defining all the routes as protected seems overkill when we only have one route for not logged in ( /login )
But not sure if we can define two routers or instead conditional show one or the other ( if it's a good practice )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think both are good. But to make code cleaner, prefer to have 2 routers.
src/NavigationBar/NavigationBar.tsx
Outdated
</div> | ||
{userContext.isLoggedIn ? ( | ||
<div className="navigation-bar__user"> | ||
{/* TODO: Need to have this as a small menu showing up */} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This menu would show up all the users path, if later on we add profile, right now this is just for logout on click
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good
@@ -0,0 +1,5 @@ | |||
export const apis = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought it would be good to handle everything in a config folder @NiiCoder
Apis urls, environment variables, etc.
@@ -0,0 +1,3 @@ | |||
export const storageNames = { | |||
user: 'pl11', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just random "paralink11" just so it's not easy to guess when looking
@@ -0,0 +1,72 @@ | |||
$elevation-card: 0 0 1px 0 rgba(8, 11, 14, 0.6), 0 16px 16px -1px rgba(8, 11, 14, 0.1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am gonna create a ticket to define a theme & variables to use accross the app & a global style. Right now this is using a lot of "custom" things. But if we can come up with a global styling ( for inputs, buttons, etc. ) this would make it easier
from: string; | ||
} | ||
|
||
const Login = (props: RouteComponentProps<{}, {}, LoginProps>): JSX.Element => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to add more comments but this is a base for now
paralinkApi.interceptors.request.use( | ||
(config: any) => { | ||
// Check for user token | ||
const accessToken = localStorage.getItem(storageNames.user); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two things here where I need your input @NiiCoder
- Should we use directly the user context instead ( and store the token in it )?
- Should we store the token in the cookies or local storage is fine ? I went for local storage but cookies could work and we could make it 'more' secure in case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this is what I was saying.
- store
- cookie
Added the hook form & validation, it would be useful for other features later on ( like that query builder ) @NiiCoder note I decide to actually keep things as they are for the moment for those reasons :
|
.finally(() => { | ||
// TODO: login loading should be set to false here | ||
}); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In login, you are using both async/await and promise patterns. Also, you are saying that the function returns Promise<any>
which is not true. In the case of async/await It returns Promise<void>
in case of Promise it returns void.
I suggest one of the following implementations:
Promise pattern
const login = (data: LoginFormData): void => {
console.log('data', data);
paralinkApi
.get('https://jsonplaceholder.typicode.com/todos')
.then(() => {
const token = 'faketokenhere';
userContext.login(token);
})
.catch((err: any) => console.error(err))
.finally(() => {});
};
Async/await pattern
const login = async (data: LoginFormData): Promise<void> => {
console.log('data', data);
try {
var token = await paralinkApi.get('https://jsonplaceholder.typicode.com/todos')
token = 'faketokenhere';
userContext.login(token);
} catch (e) {
console.error(e);
}
};
Here are some suggestions when to use one or another:
https://levelup.gitconnected.com/async-await-vs-promises-4fe98d11038f
Still need to do :
Changes
Screenshots