I am using react-admin for a dashboard. Everything works fine, but using login on a custom page (using customRoutes) is not rererendering the drawer after the redirect.
Those are my custom routes:
export default [
<Route exact path="/signup" component={SignUp} noLayout />,
];
Part of the SignUp component (the values contain phone and password, where phone is the username):
const login = useLogin();
const notify = useNotify();
const classes = useStyles();
const formik = useFormik({
initialValues: {
phone: '',
password: '',
role: '',
first_name: '',
last_name: ''
},
onSubmit: async (values, { setStatus }) => {
try {
const response = await httpClient('/api/auth/users/', {
method: 'POST',
body: JSON.stringify(values),
})
login({ phone: values.phone, password: values.password })
.catch(() => notify('Invalid phone number or password'));
} catch (e) {
notify(e.message, 'error');
}
}
});
my Admin component:
<Admin layout={Layout} dataProvider={drfProvider('/api', httpClient)} authProvider={authProvider} loginPage={LoginPage} customRoutes={customRoutes}>
{role => {
return [
<Resource name="checkins" list={CheckInList} create={CheckInCreate} show={CheckInShow} icon={PersonPinCircleIcon} options={{ label: 'Check Ins' }} />,
<Resource name="myplaces" list={role === ROLES.HOST ? PlaceList : null} edit={PlaceEdit} create={PlaceCreate} show={PlaceShow} icon={StoreIcon} options={{ label: 'My Places' }} />,
<Resource name="myrooms" list={role === ROLES.HOST ? RoomList : null} edit={RoomEdit} create={RoomCreate} show={RoomShow} icon={RoomIcon} options={{ label: 'My Rooms' }} />,
<Resource name="guests" list={role === ROLES.HOST ? GuestList : null} create={GuestCreate} show={GuestShow} icon={PeopleIcon} />,
<Resource name="places" />,
<Resource name="rooms" />,
]
}}
</Admin>
As you can see depending on the role, some routes won't be rendered. The problem is, the Admin component is only rendered in the background when I go to /signup page, and after the login redirect, it's not rerendered, so I don't see the correct resources.
Here is also my authProvider:
import jwtDecode from 'jwt-decode';
export default {
// called when the user attempts to log in
login: ({ phone, password }) => {
console.log('login start')
const request = new Request('/api/auth/jwt/create/', {
method: 'POST',
body: JSON.stringify({ phone, password }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
return fetch(request)
.then(response => {
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText);
}
return response.json();
})
.then(({ access }) => {
localStorage.setItem('token', access);
});
},
// called when the user clicks on the logout button
logout: () => {
localStorage.removeItem('token');
return Promise.resolve();
},
// called when the API returns an error
checkError: ({ status }) => {
if (status === 401 || status === 403) {
localStorage.removeItem('token');
return Promise.reject();
}
return Promise.resolve();
},
// called when the user navigates to a new location, to check for authentication
checkAuth: () => {
return localStorage.getItem('token')
? Promise.resolve()
: Promise.reject();
},
// called when the user navigates to a new location, to check for permissions / roles
getPermissions: () => {
console.log('getPermissions start')
const token = localStorage.getItem('token');
let role = null;
try {
const decodedToken = jwtDecode(token);
role = decodedToken.role;
} catch (e) {
role = '';
}
console.log('role ' + role)
return Promise.resolve(role);
}
};
A custom login page, however works correctly, so probably because we don't need a customRoute for it. I think it's about how react-admin manages the customRoutes.