How to dynamically change page titles and adapt login background design? (in v4)

Hello everyone, I cant find anything about that for the newest version online. Did anybody figure this out already? Login Page from Inferencer
42 Replies
kapa.ai
kapa.ai2y ago
Hey @l0zz1! I'm the kapa.ai support bot. I've searched through the docs to try to answer your question. :wave:
kapa.ai
kapa.ai2y ago
---------------------- To dynamically change page titles in refine v4, you can use the <Title> component from @pankod/refine. Unfortunately, there is no specific example in the provided extracts for v4. However, you can refer to the refine documentation (https://refine.dev/docs) for more information. For adapting the login background design, you can customize the login page by overriding the default login page and applying your own styles. Here's an example from the extracts:
import { useLogin } from "@refinedev/core";
import { Layout, Button, Row, Col } from "antd";
import Icon from "@ant-design/icons";

export const Login: React.FC = () => {
const { mutate: login, isLoading } = useLogin();

return (
<Layout
style={{
background: `radial-gradient(50% 50% at 50% 50%, #63386A 0%, #310438 100%)`,
backgroundSize: "cover",
}}
>
<Row
justify="center"
align="middle"
style={{
height: "100vh",
}}
>
<Col xs={22}>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
marginBottom: "28px",
}}
>
<img src="./refine.svg" alt="Refine" />
</div>
<div style={{ display: "flex", justifyContent: "center" }}>
<Button
type="primary"
size="large"
icon={
<Icon
component={() => (
<img
alt={"ethereum.png"}
src="./ethereum.png"
/>
)}
/>
}
loading={isLoading}
onClick={() => login({})}
>
SIGN-IN WITH ETHEREUM
</Button>
</div>
</Col>
</Row>
</Layout>
);
};
import { useLogin } from "@refinedev/core";
import { Layout, Button, Row, Col } from "antd";
import Icon from "@ant-design/icons";

export const Login: React.FC = () => {
const { mutate: login, isLoading } = useLogin();

return (
<Layout
style={{
background: `radial-gradient(50% 50% at 50% 50%, #63386A 0%, #310438 100%)`,
backgroundSize: "cover",
}}
>
<Row
justify="center"
align="middle"
style={{
height: "100vh",
}}
>
<Col xs={22}>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
marginBottom: "28px",
}}
>
<img src="./refine.svg" alt="Refine" />
</div>
<div style={{ display: "flex", justifyContent: "center" }}>
<Button
type="primary"
size="large"
icon={
<Icon
component={() => (
<img
alt={"ethereum.png"}
src="./ethereum.png"
/>
)}
/>
}
loading={isLoading}
onClick={() => login({})}
>
SIGN-IN WITH ETHEREUM
</Button>
</div>
</Col>
</Row>
</Layout>
);
};
In this example, the login page background is customized using the style prop of the <Layout> component. You can modify the styles according to your design preferences. ----------------------
Overview | refine
What is refine?
kapa.ai
kapa.ai2y ago
<@151783171510370305> kapa.ai is still learning and improving, please let us how it did by reacting below
conscious-sapphire
conscious-sapphire2y ago
The title worked. But do I really have to copy the login page? cant I use the old one, but change the radiant color?
rising-crimson
rising-crimson2y ago
You need to swizzle AuthPage to customize https://refine.dev/docs/api-reference/mui/components/mui-auth-page/ Unfortunately you cant change radiant color with props.
conscious-sapphire
conscious-sapphire2y ago
npm run refine swizzle
npm run refine swizzle
?
rising-crimson
rising-crimson2y ago
sorry wrong link https://refine.dev/docs/packages/documentation/cli/#swizzle bono im sorry you can customize AuthPage background like this
<AuthPage
type="updatePassword"
wrapperProps={{
style: {
background: "green",
},
}}
/>;
<AuthPage
type="updatePassword"
wrapperProps={{
style: {
background: "green",
},
}}
/>;
@l0zz1
conscious-sapphire
conscious-sapphire2y ago
😂 😂 😂 😂 😂 😂 dont be sorry man you are always sorry u r doing this in ur free time, helping me out you are great! Thanks man, I'll test it in a bit
rising-crimson
rising-crimson2y ago
🙏🏻 thanks 😄
conscious-sapphire
conscious-sapphire2y ago
works! Is there also any way to disable register? And how do you create a forgot password screen?
rising-crimson
rising-crimson2y ago
you can give registerLink={false}
conscious-sapphire
conscious-sapphire2y ago
worked! I've also seen that in the docs... but the one thing I cant find is how to connect the forgot-password page to our supabase database, so that it sends out a reset password email. Is there any predefined prop for AuthPage or something like that? Or do we need to swizzle to do such thing?
rising-crimson
rising-crimson2y ago
what you mean when you say "connect" when forgot password page is submitted. its call authProvider's forgotPassword method
conscious-sapphire
conscious-sapphire2y ago
well, it is already connected to our database, the login works. But we never defined a route or a function that tells supabase to send out a recovery email oh, let me check it wasnt defined, but I defined it:
forgotPassword: async ({ email }) => {
const { error } = await supabaseClient.auth.resetPasswordForEmail(
email, { redirectTo: "http://localhost:3000/update-password" }
);

if (error) {
return {
success: false,
error,
};
}

return {
success: true,
};
},
updatePassword: async ({newPassword}) => {
const { data, error } = await supabaseClient.auth.updateUser({password: newPassword,});

if (error) {
return {
success: false,
error,
};
}

return {
success: true,
};
}
forgotPassword: async ({ email }) => {
const { error } = await supabaseClient.auth.resetPasswordForEmail(
email, { redirectTo: "http://localhost:3000/update-password" }
);

if (error) {
return {
success: false,
error,
};
}

return {
success: true,
};
},
updatePassword: async ({newPassword}) => {
const { data, error } = await supabaseClient.auth.updateUser({password: newPassword,});

if (error) {
return {
success: false,
error,
};
}

return {
success: true,
};
}
Everything is working, but the updatePassword isnt. The page is loading and there are no undefined errors or such, but the password isnt changed. AND also, there are no success notifications, not even on the resetPasswordEmail 😄
rising-crimson
rising-crimson2y ago
hmm. i'm not familiar with this feature of supabase. i will debug and return you when is possible.
conscious-sapphire
conscious-sapphire2y ago
any news on that? By the way: Should I copy my messages and questions and create a new post? Just so that other users can search for them, if they have the same question, so that u guys dont have to answer it 100 times. 😄
rising-crimson
rising-crimson2y ago
Please do that 🙏🏻 i need to discuss with the core team before answer this supabase update-password issue.
Omer
Omer2y ago
Hey @l0zz1 , Have you reviewed our Supabase example? All the features you mentioned are already integrated. Check it out at https://refine.dev/docs/examples/data-provider/supabase/
conscious-sapphire
conscious-sapphire2y ago
I'm still working on some bug fixing, but I'll check it out in a bit. I already looked inside of the source code, but it was some time ago. Maybe it'll help now with my "new" knowledge 😄 I'll respond in a bit!
Omer
Omer2y ago
We can provide quick responses regarding Refine-related issues, but we cannot provide support for Supabase's API integration. Please use Supabase's Discord server for your Supabase API-related questions. Thank you for your understanding 🎯
conscious-sapphire
conscious-sapphire2y ago
will do!
rising-crimson
rising-crimson2y ago
Hi @l0zz1, we have discovered some points that could potentially cause issues. When redirecting with the Supabase update-password link, a token is added to localStorage and a session is created. In our example, if the check function of the authProvider detects a session, the app is opened and we cannot go to update-password. See https://github.com/refinedev/refine/blob/master/examples/data-provider-supabase/src/App.tsx#L202. Because update-password page has authenticated wrapper. What should happen is to make an update-password request with the temporary session created by Supabase for reset-password. We have not yet found a solution that adheres to best practices. Please let us know if you find one.
conscious-sapphire
conscious-sapphire2y ago
thank you! I'll tell you if I find something out, but this helps! Ok, just using the code from the example did the trick:
updatePassword: async ({ password }) => {
try {
const { data, error } = await supabaseClient.auth.updateUser({
password,
});

if (error) {
return {
success: false,
error,
};
}

if (data) {
return {
success: true,
redirectTo: "/",
};
}
} catch (error: any) {
return {
success: false,
error,
};
}
return {
success: false,
error: new Error("Update Password password failed"),
};
}
updatePassword: async ({ password }) => {
try {
const { data, error } = await supabaseClient.auth.updateUser({
password,
});

if (error) {
return {
success: false,
error,
};
}

if (data) {
return {
success: true,
redirectTo: "/",
};
}
} catch (error: any) {
return {
success: false,
error,
};
}
return {
success: false,
error: new Error("Update Password password failed"),
};
}
My guess is that the variable names do play a huge role here?
conscious-sapphire
conscious-sapphire2y ago
but why are there no notifications? Shouldnt the AuthPage already have some type of notifications, without importing and installing antd? Isnt it possible to use those? :
No description
conscious-sapphire
conscious-sapphire2y ago
Ok, I've seen that there are no success notification predefined for authprovider: auth.ts file:
export type AuthActionResponse = {
success: boolean;
redirectTo?: string;
error?: Error;
[key: string]: unknown;
};
export type AuthActionResponse = {
success: boolean;
redirectTo?: string;
error?: Error;
[key: string]: unknown;
};
So I guess you really have to use antd. But why are there success notifications when creating a new products for example? Those work without antd, right?
rising-crimson
rising-crimson2y ago
It can be work without antd if you have notificationProvider. there is no default success notification after auth operations. if you want, you can create your login page and you can open notification like this:
useLogin({
onSettled: (data) => {
if (data?.success) {
open?.({
message: "Login successful",
type: "success",
});
}
},
})
useLogin({
onSettled: (data) => {
if (data?.success) {
open?.({
message: "Login successful",
type: "success",
});
}
},
})
conscious-sapphire
conscious-sapphire2y ago
I have a notificationProvider, but can I fire a notification in authProvider.ts? So that when a success: true is set, a notification is fired as well. Im not sure if I can use antd bc it could conflict with mui.
conscious-sapphire
conscious-sapphire2y ago
I have that in the app.tsx. How can I use the component? Is that possible? I want to fire a Snackbar Notification when the passwordReset Email is sent. So it has to be inside of the authProvider.ts file. How can I user RefineSnackbarProvider to fire a Snackbar notification? I've seen it a couple of times, after a CREATE statement for example. But I can not find the code on how you did that.
Omer
Omer2y ago
You can directly use the 'open' function of the 'notificationProvider'. Please refer to this document. https://refine.dev/docs/api-reference/core/providers/notification-provider/#built-in-notification-providers
conscious-sapphire
conscious-sapphire2y ago
Any fix for this?
No description
No description
conscious-sapphire
conscious-sapphire2y ago
nothing?
rising-crimson
rising-crimson2y ago
hooks cannot call from regular javascript functions https://legacy.reactjs.org/docs/hooks-rules.html#only-call-hooks-from-react-functions you can try to call directly from notificationProvider
Rules of Hooks – React
A JavaScript library for building user interfaces
conscious-sapphire
conscious-sapphire2y ago
directly from notificationProvider? What do you mean?
rising-crimson
rising-crimson2y ago
inside your authProvider, you can call notificationProvider.show()
conscious-sapphire
conscious-sapphire2y ago
doesnt work on every import possible
No description
conscious-sapphire
conscious-sapphire2y ago
is there another path I should import?
rising-crimson
rising-crimson2y ago
i will debug and return you
conscious-sapphire
conscious-sapphire2y ago
thx!
rising-crimson
rising-crimson2y ago
with import { RefineSnackbarProvider} from "@refinedev/mui" we are using notistack@2 under the hood. we need to update this to use outside react component. issue: https://github.com/iamhosseindhv/notistack/issues/30#issuecomment-1171622850 i created notistack@3 example for you: https://codesandbox.io/s/trusting-hill-1voklb?file=/src/App.tsx:1386-1492 but with this example, we are using 2 snackbarprovider and this is not ideal. i suggest to create your notification provider until we updated notistack@2 to notistack@3 for example we implement react-toastify in this example: https://refine.dev/docs/api-reference/core/providers/notification-provider/#creating-an-notificationprovider but i don't know can u use react-toastify outside react. but i know u can use this https://react-hot-toast.com/docs/toast outside react they wrote this on the top of the page :D
Call it to create a toast from anywhere, even outside React. Make sure you add the <Toaster/> component to your app first.
Call it to create a toast from anywhere, even outside React. Make sure you add the <Toaster/> component to your app first.
conscious-sapphire
conscious-sapphire2y ago
so I have to create a new notification provider with hot-toast?
rising-crimson
rising-crimson2y ago
Your choice to select notification system. Notistack@3 great library. React hot toast is great too. We will add notistack@3 update to our backlog but I can't give a release date without talking to the core team.