Do you want to develop a web application quickly? You are at the right place! I will develop a simple movie web application with refine on the frontend and Supabase on the backend, you should continue reading. I will try to explain it step by step in a very simple way.
1. Refine setup
There are two alternative methods to set up a refine application.
The recommended way is using the superplate tool. superplate's CLI wizard will let you create and customize your application in seconds.
Alternatively, you may use the create-react-app tool to create an empty React application and then add refine module via npm.
I will use superplate-cli and select a Supabase. You can customize other options as you wish.
2. Create admin panel with refine
- We should add our Supabase url and key in supabaseClient.tsx
- Add custom login page in App.tsx
App.tsx
import { Refine } from "@pankod/refine";
import "@pankod/refine/dist/styles.min.css";
import { dataProvider } from "@pankod/refine-supabase";
import authProvider from "./authProvider";
import { supabaseClient } from "utility";
import { Login } from "./pages/login";
function App() {
return (
<Refine
dataProvider={dataProvider(supabaseClient)}
authProvider={authProvider}
LoginPage={Login}
></Refine>
);
}
export default App;
Login page
import React from "react";
import {
Row,
Col,
AntdLayout,
Card,
Typography,
Form,
Input,
Button,
Checkbox,
} from "@pankod/refine";
import "./styles.css";
import { useLogin } from "@pankod/refine";
const { Text, Title } = Typography;
export interface ILoginForm {
username: string;
password: string;
remember: boolean;
}
export const Login: React.FC = () => {
const [form] = Form.useForm<ILoginForm>();
const { mutate: login } = useLogin<ILoginForm>();
const CardTitle = (
<Title level={3} className="title">
Sign in your account
</Title>
);
return (
<AntdLayout className="layout">
<Row
justify="center"
align="middle"
style={{
height: "100vh",
}}
>
<Col xs={22}>
<div className="container">
<div className="imageContainer">
<img src="./refine.svg" alt="Refine Logo" />
</div>
<Card title={CardTitle} headStyle={{ borderBottom: 0 }}>
<Form<ILoginForm>
layout="vertical"
form={form}
onFinish={(values) => {
login(values);
}}
requiredMark={false}
initialValues={{
remember: false,
email: "info+refineflix@refine.dev",
password: "refineflix",
}}
>
<Form.Item
name="email"
label="Email"
rules={[{ required: true, type: "email" }]}
>
<Input size="large" placeholder="Email" />
</Form.Item>
<Form.Item
name="password"
label="Password"
rules={[{ required: true }]}
style={{ marginBottom: "12px" }}
>
<Input type="password" placeholder="●●●●●●●●" size="large" />
</Form.Item>
<div style={{ marginBottom: "12px" }}>
<Form.Item name="remember" valuePropName="checked" noStyle>
<Checkbox
style={{
fontSize: "12px",
}}
>
Remember me
</Checkbox>
</Form.Item>
<a
style={{
float: "right",
fontSize: "12px",
}}
href="#"
>
Forgot password?
</a>
</div>
<Button type="primary" size="large" htmlType="submit" block>
Sign in
</Button>
</Form>
<div style={{ marginTop: 8 }}>
<Text style={{ fontSize: 12 }}>
Don’t have an account?{" "}
<a href="#" style={{ fontWeight: "bold" }}>
Sign up
</a>
</Text>
</div>
</Card>
</div>
</Col>
</Row>
</AntdLayout>
);
};
.layout {
background: radial-gradient(50% 50% at 50% 50%, #63386a 0%, #310438 100%);
background-size: "cover";
}
.container {
max-width: 408px;
margin: auto;
}
.title {
text-align: center;
color: #626262;
font-size: 30px;
letter-spacing: -0.04em;
}
.imageContainer {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16px;
}
You can use default user for login.
- Create movies list page with add a resource in App.tsx
import { Refine, Resource } from "@pankod/refine";
import "@pankod/refine/dist/styles.min.css";
import { dataProvider } from "@pankod/refine-supabase";
import authProvider from "./authProvider";
import { supabaseClient } from "utility";
import {
AdminMovieList,
} from "./pages/admin/movies";
import { Login } from "./pages/login";
function App() {
return (
<Refine
dataProvider={dataProvider(supabaseClient)}
authProvider={authProvider}
LoginPage={Login}
>
<Resource
name="movies"
list={AdminMovieList}
options={{
route: "admin/movies",
}}
/>
</Refine>
);
}
export default App;
- AdminMovieList page ```tsx
import {
List,
Table,
useTable,
IResourceComponentsProps,
Space,
EditButton,
ShowButton,
getDefaultSortOrder,
CreateButton,
DeleteButton,
} from "@pankod/refine";
import { IMovies } from "interfaces";
export const AdminMovieList: React.FC = () => {
const { tableProps, sorter } = useTable({
initialSorter: [
{
field: "id",
order: "asc",
},
],
});
return (
}}>