0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

弱々エンジニアの生成AIを用いた開発 #5-3 (フロントエンド開発 ログイン画面UI~ユーザ登録)

Posted at

お盆でばたばたして作業が全然進みませんでした…
ちょっと更新頻度落ちます

前回のおさらい

前回やったこと

  • VSCodeポータブルの環境構築
  • VSCodeとCodeiumの連携
  • Firebaseを使うための設定

今回やること

  • ログイン画面UI作成
  • ユーザ登録UI作成
  • Firebase Authenticationへユーザ登録の確認

とりあえず画面遷移図で表すと、ここを進めようかと
image.png

ログイン画面UI作成

今回UIを作成するにあたり、前回VSCodeの拡張に入れた
Codeiumを使用してログイン画面及び動作コードを作成していきたいと思います

VSCode開いて、WindsurfのタブでAIに聞いてみましょう

ReactとFirebase Authenticationを使用して、ログイン画面を作る
FirebaseのAPIキーなどは.envファイルに定義されている
※Login.jsとFirebase.jsのコードが出力された為、実装する図

      ∧_∧
     (・ω・ ) カタカタカタカタ
   _| ̄ ̄||_))_
 /旦|――||// /|
 | ̄ ̄ ̄ ̄ ̄| ̄| . |
 |_____|三|/

npm start ...っと

うーん…
なんかコンパイルエラーがでるなぁ…

Firebase.jsの中身を見てみると

import firebase from 'firebase/app';
import 'firebase/auth';

const firebaseConfig = {
  apiKey: process.env.REACT_APP_API_KEY,
  authDomain: process.env.REACT_APP_AUTH_DOMAIN,
  projectId: process.env.REACT_APP_PROJECT_ID,
  storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_APP_ID,
};

firebase.initializeApp(firebaseConfig);

export default firebase;

んー… REACT_APP_〇〇 の設定内容が .env ファイルと違うな
.env の方は REACT_APP_FIREBASE_〇〇 ってなっているような…

これ、Codeiumはインライン化したから
指示した内部設定ファイルを見にいって、コードに反映してくれるかと思ったら
してくれてないっぽいな

しょうがないから、.env の中身を見るように指示してみるか…

.envファイルの設定キーとFirebase.jsの設定キーが一致していない
.envファイルの方に設定キーを合わせる
Firebase.jsの内容出力中…

先ほどのFirebase.jsの REACT_APP_〇〇 の箇所が
REACT_APP_FIREBASE_〇〇 に変わっている事を
確認して、ソースコードにコピペ、そしてまたnpm startっと

..::::::::::::::::::::
  ...::::::::::::::::
 . ......::::::::::::
     Λ_Λ...::::::
   /彡ミヽ )ー、::::
  /:ノ:ヽ \::|.:::
  /:/::  \ ヽ|.:::
 ̄(_ノ ̄ ̄ ̄\_ノ ̄ ̄

なぜ、動かん…
ERROR in ./src/firebase.js 13:0-22
export 'default' (imported as 'firebase') was not found in 'firebase/app' (possible exports:
FirebaseError, SDK_VERSION, _DEFAULT_ENTRY_NAME, _addComponent, _addOrOverwriteComponent,
_apps, _clearComponents, _components, _getProvider, _isFirebaseApp, _isFirebaseServerApp,
_isFirebaseServerAppSettings, _registerComponent, _removeServiceInstance, _serverApps,
deleteApp, getApp, getApps, initializeApp, initializeServerApp, onLog, registerVersion,
setLogLevel)

見てる感じ、firebase.jsの13行目にエラーがあって、firebase/appにdefaultという
エクスポート内容は見つからないと言っていますね

なるほど… んでどう変えれば良いのか?
このエラーメッセージをそのまま、Codeiumに投げてみます

ERROR in ./src/firebase.js 13:0-22
このエラーは、firebase/appモジュールからdefaultエクスポートが見つからないことを示しています
firebase/appモジュールは、FirebaseのCore SDKを提供しますが、defaultエクスポートはありません。
代わりに、firebase/appモジュールからinitializeApp関数をインポートする必要があります。
以下のコードを変更してください。

~以下、firebase.jsのコードの変更内容を出力~

ふむふむ
… なんで最初からinitializeApp関数をインポートしてくれてないんすかね?
これは指示が悪かったのか、それともCodeium君が行間を読み取ってくれなかったのか…

Grok君とかClaudeさんとかは、割と詳細に記述しなくても
いい感じに回答が返ってきてたので、なんとなーく
同じレベルで考えてプロンプト打ってましたけど
これ結構具体的に打たなきゃ駄目かもなぁ…

後、Login.jsの中で
import firebase from 'firebase/app';
となっている行もあったので、ここも現在のディレクトリ構造に合わせて修正必要かぁ…

そういや、もうひとつエラーでてたな…

ERROR in ./src/Login.js 7:0-54
Module not found: Error: Can't resolve '@material-ui/core' in '.\cbit\src'

こちらについても、Codeiumに投げてみます

ERROR in ./src/Login.js 7:0-54

このエラーは、@material-ui/coreモジュールが見つからないことを示しています。

@material-ui/coreモジュールは、Material-UIライブラリの一部です。
Material-UIライブラリをインストールしていない場合、またはインストールした後に
パッケージを更新していない場合に発生する可能性があります。

以下の手順を実行して、@material-ui/coreモジュールをインストールしてください。

うーん… materialはpackage.jsonで確か定義して、npm installしたはずなんだけどな…
一回見直してみますか…

"dependencies":{
    "@emotion/react": "^11.10.0",
    "@emotion/styled": "^11.10.0",
    "@mui/material": "^5.11.0",

いや、ちゃんと書いてあるやん
もしかしなくても、@material-ui/core@mui/material は別物…?
Codeiumに@muiの方でインストールしたよって書いてみるか

"@mui/material": "^5.11.0" でmaterialをインストールしたので
先ほどのログイン画面はその依存関係を使うようにしてください

Codeiumの回答

Login.js
- import { Button, TextField } from '@material-ui/core';
+ import { Button, TextField } from '@mui/material';

やっぱかーい… ちょっとGoogle先生で調べてみたら
@material-ui/core は前のバージョン v4 のもので
@mui/material が現行のバージョン v5 となっていました
ってかブランドそのものが違うものになってたのね…

こういう事があるから、やっぱりちゃんと調べなきゃいけないんだなぁ…

とりあえず、今回は動けばどちらでもよかったんですが
@mui~はReactとreact-domが 17.0.0 を最小バージョンとしてサポートすると
公式に書いてあったので今回は@mui~の方で使用していきたいと思います
後ついでにnode.jsも対応バージョンは 12.7 からって書いてたので確認しておきます


※今回使用しているバージョンは下記の通り
  • React:18.2.0
  • react-dom:18.2.0
  • node.js:18.20.8

さてと…
Login.jsのコードも書き換えたので今度こそ動いてくれよ…?

npmstart.jpg

やっときたぁ…
そして、表示された画面がこれ

login-1.jpg

うーん すごく簡素

まぁ、textfieldとButtonしか使ってなかったから
何となく察してた

これ、Grok君に作らせたらどうなるんやろな…
ちょっと長くなりそうなので実装工程は割愛させていただき
Grok君の方に同じようなプロンプトで入力してみた結果を実装

image.png

おんやぁ…?
なんかGrok君の方、ほんのちょっとだけいい感じな気がする
あんまり変わらんけど、ログインボタンはちゃんとボタンっぽくなっているし…

これCodeiumで作るよりGrokの方が良くないかと思い始めた感じです

ちなみにフォルダ、ファイル構成もCodeiumとGrokは少し違って

Codeium
image.png

Grok
image.png

となってます
※ちょっと途中でユーザ登録用の画面も実装しちゃいました

これなら、Grokの方がフォルダ構成的にわかりやすいかなぁ…?

【審議中】
    ∧,,∧  ∧,,∧
 ∧ (´・ω・) (・ω・`) ∧∧
( ´・ω) U) ( つと ノ(ω・` )
| U ( ´・) (・` ) と ノ
u-u (l   ) (   ノu-u
    `u-u'. `u-u'

… Codeium君には悪いけど、エラー解消とかで手伝ってもらう形にして
Grok君の方で実装系を組む感じが、良さそうな気がしています
多分、機能概要とかそこらへんもGrokに任せてたからだろうな…

Grok君の方を本流として採用していく事として
Gitの中身をそちらに書き換えておきます…

ここまで来るのに結構時間かかったなぁ…

途中で実装したユーザ登録画面はこんな感じです
※ログイン画面 ⇔ 登録画面 で遷移できるように組んでいます
(画面遷移図的には行かないけど、今回はユーザ登録確認まで実行したい)

image.png

Login.js / Signup.js

一応今回Grok君に生成してもらったコードが下記の通りです

//Login.js
import React, { useState } from 'react';
import { signInWithEmailAndPassword } from 'firebase/auth';
import { auth } from '../../utils/firebase';
import { useNavigate } from 'react-router-dom';
import { TextField, Button, Box, Typography, Alert } from '@mui/material';

const Login = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const navigate = useNavigate();

  const handleLogin = async (e) => {
    e.preventDefault();
    try {
      await signInWithEmailAndPassword(auth, email, password);
      navigate('/');
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <Box sx={{ maxWidth: 400, mx: 'auto', mt: 8, p: 2 }}>
      <Typography variant="h4" gutterBottom>ログイン</Typography>
      {error && <Alert severity="error">{error}</Alert>}
      <form onSubmit={handleLogin}>
        <TextField
          label="Email"
          type="email"
          fullWidth
          margin="normal"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          required
        />
        <TextField
          label="Password"
          type="password"
          fullWidth
          margin="normal"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          required
        />
        <Button type="submit" variant="contained" fullWidth sx={{ mt: 2 }}>
          ログイン
        </Button>
      </form>
      <Button onClick={() => navigate('/signup')} sx={{ mt: 1 }}>
        ユーザー登録はこちら
      </Button>
    </Box>
  );
};

export default Login;
//Singup.js
import React, { useState } from 'react';
import { createUserWithEmailAndPassword } from 'firebase/auth';
import { auth } from '../../utils/firebase';
import { useNavigate } from 'react-router-dom';
import { TextField, Button, Box, Typography, Alert } from '@mui/material';

const Signup = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const navigate = useNavigate();

  const handleSignup = async (e) => {
    e.preventDefault();
    try {
      await createUserWithEmailAndPassword(auth, email, password);
      navigate('/login');
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <Box sx={{ maxWidth: 400, mx: 'auto', mt: 8, p: 2 }}>
      <Typography variant="h4" gutterBottom>ユーザー登録</Typography>
      {error && <Alert severity="error">{error}</Alert>}
      <form onSubmit={handleSignup}>
        <TextField
          label="Email"
          type="email"
          fullWidth
          margin="normal"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          required
        />
        <TextField
          label="Password"
          type="password"
          fullWidth
          margin="normal"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          required
        />
        <Button type="submit" variant="contained" fullWidth sx={{ mt: 2 }}>
          ユーザー登録
        </Button>
      </form>
      <Button onClick={() => navigate('/login')} sx={{ mt: 1 }}>
        既にアカウントをお持ちの方はログインページへ
      </Button>
    </Box>
  );
};

export default Signup;

ユーザー登録(Firebase Authentication)

んじゃあ、後は実際にFirebase Authenticationにユーザ登録する所へ行きたいと思います
とはいえ、Grok君に出力させる際、Firebase Authentication認証に登録する形で
とお願いしたら、簡単に登録するところまで実装できちゃってたんですよね…

なので、↑ のコードでFirebase Authenticationにユーザ登録までできちゃいました

確認した結果がこちら
Firebase_UserAdded.jpg

登録できたので消し消しっと…

メールアドレスでの認証登録まではできましたが
Googleアカウント連携で登録までは実装してないですね

今回は長くなったので、次回はGoogleアカウント認証~ダッシュボードの型枠
作りくらいまで、やれればいいなと思っています

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?