iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
Modern Web

Laravel 實務筆記系列 第 11

補充: 建立 Todo list 畫面

發現昨天的介紹中漏掉新增 Todo 的畫面是怎麼來的,補充一下。

安裝 React Material UI

加載套件

yarn add @material-ui/core

載入 Roboto 字型,可以用 cdn 的方式,在 app.blade.php 加上 link

// resources\views\app.blade.php
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        ...
        <!-- 加這行 -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
    </head>
    <body class="font-sans antialiased">
        ...
    </body>
</html>

載入 Font-icon,一樣用 cdn

// resources\views\app.blade.php
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        ...
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
        <!-- 加這行 -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
    </head>
    <body class="font-sans antialiased">
        ...
    </body>
</html>

如果需要 svg 圖示,載入套件

yarn add @material-ui/icons

編譯

如果不是在容器裡的話,可以執行更新畫面的指令:

npm run watch

這個指令會讓 laravel-mix 監聽程式碼的更新並自動打包,讓畫面可以同步程式碼的改動。

不過在容器中的話 laravel-mix 會無法監聽到程式碼的更新,要改成用定時檢查的方式觸發更新,

sail npm run watch-poll

可以到 Dashboard 試試

// resources\js\Pages\Dashboard.js
...
import Button from "@material-ui/core/Button";

export default function Dashboard(props) {
    return (
        <Authenticated ...>
            //...

            // 加一顆按鈕
            <Button variant="contained" color="primary">
                Hello world
            </Button>
        </Authenticated>
    );
}

存檔後等 mix 跑完,重新整理畫面後應該會出現一個按鈕

添加 Form

接著來建立基礎的 todo 新增表單

//resources\js\Pages\Dashboard.js
import React from "react";
import Authenticated from "@/Layouts/Authenticated";
import clsx from "clsx";
import {
    Container,
    Button,
    List,
    ListItem,
    ListItemText,
    TextField,
    Grid,
} from "@material-ui/core";
import { Head, Link, useForm } from "@inertiajs/inertia-react";
import { Inertia } from "@inertiajs/inertia";

import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles((theme) => ({
    textField: {
        marginRight: theme.spacing(1),
    },
}));

export default function Dashboard(props) {
    const classes = useStyles();
    const todos = [{ name: "todo1" }, { name: "todo2" }];
    const { data, setData, post, processing, errors, reset, transform } =
        useForm({
            todo: "",
        });

    const handleChange = (event) => {
        setData(
            event.target.name,
            event.target.type === "checkbox"
                ? event.target.checked
                : event.target.value
        );
    };

    const submit = (e) => {
        e.preventDefault();
        // post to api
    };

    return (
        <Authenticated
            auth={props.auth}
            errors={props.errors}
            header={
                <h2 className="font-semibold text-xl text-gray-800 leading-tight">
                    Dashboard
                </h2>
            }
        >
            <Head title="Dashboard" />

            <div className="py-12">
                <div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
                    <div className="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                        <div className="p-6 bg-white border-b border-gray-200">
                            You logged in!
                        </div>
                    </div>
                </div>
            </div>
            <Container>
                <form onSubmit={submit}>
                    <Grid
                        container
                        direction="row"
                        justifyContent="flex-start"
                        alignItems="flex-end"
                    >
                        <TextField
                            className={clsx(classes.textField)}
                            id="todo"
                            label="Todo"
                            name="todo"
                            value={data.todo}
                            onChange={handleChange}
                        />
                        <Button
                            type="submit"
                            variant="contained"
                            color="primary"
                            disabled={processing}
                        >
                            Add
                        </Button>
                    </Grid>
                </form>
                <List>
                    {todos.map((item) => (
                        <ListItem button>
                            <ListItemText primary={item.name} />
                        </ListItem>
                    ))}
                </List>
            </Container>
        </Authenticated>
    );
}

References

Material-UI : Installation
Laravel-mix watch polling

上一篇
Eloquent ORM - 寫入資料
下一篇
Eloquent ORM - 讀取資料
系列文
Laravel 實務筆記30

尚未有邦友留言

立即登入留言