Skip to content

Commit 202274e

Browse files
authored
Merge pull request #8351 from marmelab/tutorial-vite
[Doc] Update the tutorial to use Vite instead of create-react-app
2 parents eb33ba4 + 788c774 commit 202274e

26 files changed

+653
-684
lines changed

docs/Tutorial.md

+360-340
Large diffs are not rendered by default.

examples/tutorial/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" href="/favicon.ico" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite + React + TS</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>

examples/tutorial/package.json

+22-23
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
{
2-
"name": "tutorial",
3-
"version": "4.0.0",
4-
"private": true,
5-
"dependencies": {
6-
"@mui/icons-material": "^5.0.1",
7-
"@mui/material": "^5.0.2",
8-
"ra-data-json-server": "^4.0.0",
9-
"react": "^17.0.0",
10-
"react-admin": "^4.0.0",
11-
"react-dom": "^17.0.0",
12-
"react-scripts": "^5.0.0"
13-
},
14-
"scripts": {
15-
"start": "react-scripts start",
16-
"build": "react-scripts build",
17-
"eject": "react-scripts eject"
18-
},
19-
"browserslist": [
20-
">0.2%",
21-
"not dead",
22-
"not ie <= 11",
23-
"not op_mini all"
24-
]
2+
"name": "tutorial",
3+
"version": "4.0.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "tsc && vite build",
9+
"preview": "vite preview"
10+
},
11+
"dependencies": {
12+
"ra-data-json-server": "^4.5.0",
13+
"react": "^18.2.0",
14+
"react-admin": "^4.5.0",
15+
"react-dom": "^18.2.0"
16+
},
17+
"devDependencies": {
18+
"@types/react": "^18.0.22",
19+
"@types/react-dom": "^18.0.7",
20+
"@vitejs/plugin-react": "^2.2.0",
21+
"typescript": "^4.6.4",
22+
"vite": "^3.2.0"
23+
}
2524
}

examples/tutorial/public/index.html

-40
This file was deleted.

examples/tutorial/public/manifest.json

-15
This file was deleted.

examples/tutorial/src/App.css

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#root {
2+
max-width: 1280px;
3+
margin: 0 auto;
4+
padding: 2rem;
5+
text-align: center;
6+
}
7+
8+
.logo {
9+
height: 6em;
10+
padding: 1.5em;
11+
will-change: filter;
12+
}
13+
.logo:hover {
14+
filter: drop-shadow(0 0 2em #646cffaa);
15+
}
16+
.logo.react:hover {
17+
filter: drop-shadow(0 0 2em #61dafbaa);
18+
}
19+
20+
@keyframes logo-spin {
21+
from {
22+
transform: rotate(0deg);
23+
}
24+
to {
25+
transform: rotate(360deg);
26+
}
27+
}
28+
29+
@media (prefers-reduced-motion: no-preference) {
30+
a:nth-of-type(2) .logo {
31+
animation: logo-spin infinite 20s linear;
32+
}
33+
}
34+
35+
.card {
36+
padding: 2em;
37+
}
38+
39+
.read-the-docs {
40+
color: #888;
41+
}
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,35 @@
1-
import * as React from 'react';
1+
import { Admin, Resource } from 'react-admin';
2+
import jsonServerProvider from 'ra-data-json-server';
23
import PostIcon from '@mui/icons-material/Book';
34
import UserIcon from '@mui/icons-material/Group';
4-
import { Admin, Resource, ListGuesser } from 'react-admin';
5-
import jsonServerProvider from 'ra-data-json-server';
65

7-
import { PostList, PostEdit, PostCreate, PostShow } from './posts';
6+
import { PostList, PostEdit, PostCreate } from './posts';
87
import { UserList } from './users';
9-
import Dashboard from './Dashboard';
10-
import authProvider from './authProvider';
8+
import { Dashboard } from './Dashboard';
9+
import { authProvider } from './authProvider';
10+
11+
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
1112

1213
const App = () => (
1314
<Admin
14-
dataProvider={jsonServerProvider(
15-
'https://jsonplaceholder.typicode.com'
16-
)}
1715
authProvider={authProvider}
16+
dataProvider={dataProvider}
1817
dashboard={Dashboard}
1918
>
2019
<Resource
2120
name="posts"
22-
icon={PostIcon}
2321
list={PostList}
2422
edit={PostEdit}
2523
create={PostCreate}
26-
show={PostShow}
24+
icon={PostIcon}
25+
/>
26+
<Resource
27+
name="users"
28+
list={UserList}
29+
icon={UserIcon}
30+
recordRepresentation="name"
2731
/>
28-
<Resource name="users" icon={UserIcon} list={UserList} />
29-
<Resource name="comments" list={ListGuesser} />
3032
</Admin>
3133
);
34+
3235
export default App;

examples/tutorial/src/Dashboard.js

-11
This file was deleted.

examples/tutorial/src/Dashboard.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Card, CardContent, CardHeader } from '@mui/material';
2+
3+
export const Dashboard = () => (
4+
<Card>
5+
<CardHeader title="Welcome to the administration" />
6+
<CardContent>Lorem ipsum sic dolor amet...</CardContent>
7+
</Card>
8+
);

examples/tutorial/src/MyUrlField.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { useRecordContext } from 'react-admin';
2+
import { Link } from '@mui/material';
3+
import LaunchIcon from '@mui/icons-material/Launch';
4+
5+
const MyUrlField = ({ source }: { source: string }) => {
6+
const record = useRecordContext();
7+
return record ? (
8+
<Link href={record[source]} sx={{ textDecoration: 'none' }}>
9+
{record[source]}
10+
<LaunchIcon sx={{ fontSize: 15, ml: 1 }} />
11+
</Link>
12+
) : null;
13+
};
14+
15+
export default MyUrlField;
+1
Loading

examples/tutorial/src/authProvider.js examples/tutorial/src/authProvider.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
export default {
1+
export const authProvider = {
22
// called when the user attempts to log in
3-
login: ({ username }) => {
3+
login: ({ username }: { username: string }) => {
44
localStorage.setItem('username', username);
55
// accept all username/password combinations
66
return Promise.resolve();
@@ -11,7 +11,7 @@ export default {
1111
return Promise.resolve();
1212
},
1313
// called when the API returns an error
14-
checkError: ({ status }) => {
14+
checkError: ({ status }: { status: number }) => {
1515
if (status === 401 || status === 403) {
1616
localStorage.removeItem('username');
1717
return Promise.reject();

examples/tutorial/src/index.js

-8
This file was deleted.

examples/tutorial/src/index.module.css

-5
This file was deleted.

examples/tutorial/src/logo.svg

-7
This file was deleted.

examples/tutorial/src/main.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom/client';
3+
import App from './App';
4+
5+
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
6+
<React.StrictMode>
7+
<App />
8+
</React.StrictMode>
9+
);

examples/tutorial/src/posts.js

-80
This file was deleted.

0 commit comments

Comments
 (0)