🤖

GPT-4にUIまで作らせるのもDDDなら超簡単

2023/03/16に公開

この記事内で使用したChatGPTスレッドの続きです
https://zenn.dev/masaori/articles/4bf531a1b1193d

このPropsを受け取る画面を作って

GPT-4への追加のお願いはこちら

reactとMaterial UIを使用して、Material Designに準拠したデスクトップ向けのReactコンポーネントを実装してください。このコンポーネントはUserListPagePropsをPropsとして受け取ってください。

こんだけ。

で、帰ってきたコードがこちら。

import React from 'react';
import {
  Container,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  Typography,
} from '@material-ui/core';
import { UserListPageProps } from './types';

export const UserList: React.FC<UserListPageProps> = ({ users }) => {
  return (
    <Container>
      <Typography variant="h4" component="h1" gutterBottom>
        Users
      </Typography>
      <TableContainer component={Paper}>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>ID</TableCell>
              <TableCell>Name</TableCell>
              <TableCell>Tasks</TableCell>
              <TableCell>Groups</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {users.map((user) => (
              <TableRow key={user.id}>
                <TableCell>{user.id}</TableCell>
                <TableCell>{user.name}</TableCell>
                <TableCell>
                  {user.tasks.map((task) => (
                    <div key={task.id}>{task.description}</div>
                  ))}
                </TableCell>
                <TableCell>
                  {user.groups.map((group) => (
                    <div key={group.id}>
                      {group.name} ({group.organization.name})
                    </div>
                  ))}
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </Container>
  );
};

参照系としては完璧ですね。でも更新もしたいですよね?

というわけでこちらを追加。

以下ができるようなUIにすることはできますか?
- 新しいUserの作成
- 存在するUserの削除
- 存在するUserの名前を編集
- 存在するUserの所属するGroupの変更

結果がこちら

もちろんです。以下は、新しいUserの作成、既存のUserの削除、名前の編集、所属するGroupの変更ができるように拡張したUserListコンポーネントです。
import React, { useState } from 'react';
import {
  Container,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  Typography,
  IconButton,
  TextField,
  Button,
  MenuItem,
  Select,
} from '@material-ui/core';
import { Delete as DeleteIcon, Edit as EditIcon, Save as SaveIcon } from '@material-ui/icons';
import { UserListPageProps } from './types';

export const UserList: React.FC<UserListPageProps> = ({ users }) => {
  const [editingUserId, setEditingUserId] = useState<string | null>(null);
  const [editedUserName, setEditedUserName] = useState('');
  const [selectedGroupId, setSelectedGroupId] = useState('');
  const [newUserName, setNewUserName] = useState('');

  const handleEdit = (userId: string, userName: string) => {
    setEditingUserId(userId);
    setEditedUserName(userName);
  };

  const handleSave = (userId: string) => {
    // Call API to update user name
    console.log('Updated user:', userId, editedUserName);
    setEditingUserId(null);
    setEditedUserName('');
  };

  const handleDelete = (userId: string) => {
    // Call API to delete user
    console.log('Deleted user:', userId);
  };

  const handleGroupChange = (userId: string, event: React.ChangeEvent<{ value: unknown }>) => {
    setSelectedGroupId(event.target.value as string);
    // Call API to change user's group
    console.log('Changed user group:', userId, event.target.value);
  };

  const handleNewUser = () => {
    // Call API to create new user
    console.log('Created new user:', newUserName);
    setNewUserName('');
  };

  return (
    <Container>
      <Typography variant="h4" component="h1" gutterBottom>
        Users
      </Typography>
      <TextField
        label="New User"
        value={newUserName}
        onChange={(e) => setNewUserName(e.target.value)}
        style={{ marginBottom: 16 }}
      />
      <Button variant="contained" color="primary" onClick={handleNewUser}>
        Create
      </Button>
      <TableContainer component={Paper}>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>ID</TableCell>
              <TableCell>Name</TableCell>
              <TableCell>Tasks</TableCell>
              <TableCell>Groups</TableCell>
              <TableCell>Actions</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {users.map((user) => (
              <TableRow key={user.id}>
                <TableCell>{user.id}</TableCell>
                <TableCell>
                  {editingUserId === user.id ? (
                    <TextField
                      value={editedUserName}
                      onChange={(e) => setEditedUserName(e.target.value)}
                    />
                  ) : (
                    user.name
                  )}
                </TableCell>
                <TableCell>
                  {user.tasks.map((task) => (
                    <div key={task.id}>{task.description}</div>
                  ))}
                </TableCell>
                <TableCell>
                  <Select
                    value={selectedGroupId}
                    onChange={(e) => handleGroupChange(user.id, e)}
                    displayEmpty
                  >
                    <MenuItem value="" disabled>
                      Choose Group
                    </MenuItem>
                    {user.groups.map((group) => (
                      <MenuItem key={group.id} value={group.id}>
                        {group.name} ({group.organization.name})
                      </MenuItem>
                    ))}
                  </Select>
                </TableCell>
                <TableCell>
                  {editingUserId === user.id ? (
                    <>
                      <IconButton onClick={() => handleSave(user.id)}>
                        <SaveIcon />
                      </IconButton>
                      <IconButton onClick={() => setEditingUserId(null)}>
                        <EditIcon />
                      </IconButton>
                    </>
                  ) : (
                    <IconButton onClick={() => handleEdit(user.id, user.name)}>
                      <EditIcon />
                    </IconButton>
                  )}
                  <IconButton onClick={() => handleDelete(user.id)}>
                    <DeleteIcon />
                  </IconButton>
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </Container>
  );
};
これで、ユーザーのグループの変更が可能になります。ただし、このコードはサンプルであり、console.logを使ってイベントを表示しています。実際のアプリケーションでは、API呼び出しや状態管理ライブラリ(Reduxなど)を使用して、ユーザー情報を適切に更新してください。

もちろんです。

(↑こういうこといちいち言ってくれるのもなんか気分的にイイ)

凄ない??

念の為すごいポイントを熱っぽく語る。

  • 言ってもないのにアイコン設置してるよ!
  • 言ってもないのに「Edit/Save」UIを実装してるよ!
  • handle~~はスタブにしといたから適切にAPIとか呼んでね、だって!

このレベルのフリーランスエンジニアいたら月120万(税込)くらいは考えますね。マジの話。

結論

すごい。

Discussion