使用生成式人工智能构建无服务器 Web 应用程序

教程

模块五:构建前端

在本模块中,您将创建一个应用程序前端并将其连接到已经构建的云后端。

概述

在本模块中,您将更新在模块一中创建的网站,以使用 Amplify UI 组件库来构建整个用户身份验证流程,允许用户注册、登录和重置密码,并调用 GraphQL API 来使用客户查询根据成分清单生成配方。

您将学到的内容

  • 安装 Amplify 客户端库
  • 配置 React 应用程序以添加身份验证流程并调用 GraphQL API

实施

 完成时间

5 分钟

  • 项目将需要两个 Amplify 库。主 aws-amplify 库包含用于将应用程序的前端连接到后端的所有客户端 API,而 @aws-amplify/ui-react 库包含框架特定 UI 组件。

    1.打开一个新的终端窗口,导航到项目根文件夹 (ai-recipe-generator),然后运行以下命令来安装库。

    npm install aws-amplify @aws-amplify/ui-react
  • 1.在本地计算机上,导航到 ai-recipe-generator/src/index.css 文件,然后使用以下代码对其进行更新,以使应用程序 UI 居中。然后,保存文件。

    :root {
      font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
      line-height: 1.5;
      font-weight: 400;
    
      color: rgba(255, 255, 255, 0.87);
    
      font-synthesis: none;
      text-rendering: optimizeLegibility;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    
      max-width: 1280px;
      margin: 0 auto;
      padding: 2rem;
    
    }
    
    .card {
      padding: 2em;
    }
    
    .read-the-docs {
      color: #888;
    }
    
    .box:nth-child(3n + 1) {
      grid-column: 1;
    }
    .box:nth-child(3n + 2) {
      grid-column: 2;
    }
    .box:nth-child(3n + 3) {
      grid-column: 3;
    }

    2.使用以下代码更新 src/App.css 文件以设置成分表单的样式。然后,保存文件。

    .app-container {
    
      margin: 0 auto;
      padding: 20px;
      text-align: center;
    }
    
    .header-container {
      padding-bottom: 2.5rem;
      margin:  auto;
      text-align: center;
    
      align-items: center;
      max-width: 48rem;
      
      
    }
    
    .main-header {
      font-size: 2.25rem;
      font-weight: bold;
      color: #1a202c;
    }
    
    .main-header .highlight {
      color: #2563eb;
    }
    
    @media (min-width: 640px) {
      .main-header {
        font-size: 3.75rem;
      }
    }
    
    .description {
    
      font-weight: 500;
      font-size: 1.125rem;
      max-width: 65ch;
      color: #1a202c;
    }
    
    .form-container {
      margin-bottom: 20px;
    }
    
    .search-container {
      display: flex;
      flex-direction: column;
      gap: 10px;
      align-items: center;
    }
    
    .wide-input {
      width: 100%;
      padding: 10px;
      font-size: 16px;
      border: 1px solid #ccc;
      border-radius: 4px;
    }
    
    .search-button {
      width: 100%; /* Make the button full width */
      max-width: 300px; /* Set a maximum width for the button */
      padding: 10px;
      font-size: 16px;
      background-color: #007bff;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }
    
    .search-button:hover {
      background-color: #0056b3;
    }
    
    .result-container {
      margin-top: 20px;
      transition: height 0.3s ease-out;
      overflow: hidden;
    }
    
    .loader-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 10px;
    }
    
    .result {
      background-color: #f8f9fa;
      border: 1px solid #e9ecef;
      border-radius: 4px;
      padding: 15px;
      white-space: pre-wrap;
      word-wrap: break-word;
      color: black;
      font-weight: bold;
      text-align: left; /* Align text to the left */
    }
  • 1.在本地计算机上,导航到 ai-recipe-generator/src/main.tsx 文件,然后使用以下代码对其进行更新。然后,保存文件。

    • 该代码将使用 Amplify Authenticator 组件来支撑整个用户身份验证流程,从而使用户能够注册、登录、重置密码和确认登录以进行多重身份验证(MFA)。
    import React from "react";
    import ReactDOM from "react-dom/client";
    import App from "./App.jsx";
    import "./index.css";
    import { Authenticator } from "@aws-amplify/ui-react";
    
    ReactDOM.createRoot(document.getElementById("root")!).render(
      <React.StrictMode>
        <Authenticator>
          <App />
        </Authenticator>
      </React.StrictMode>
    );

    2.打开 ai-recipe-generator/src/App.tsx 文件,然后使用以下代码对其进行更新。然后,保存文件。

    • 代码首先使用客户端配置文件 (amplify_outputs.json) 配置 Amplify 库。然后,使用 generateClient () 函数生成一个数据客户端。该应用程序向用户显示一个表格,用于提交成分清单。提交后,它将使用数据客户端将清单传递给 askBedrock 查询,检索生成的配方,然后向用户展示。
    import { FormEvent, useState } from "react";
    import { Loader, Placeholder } from "@aws-amplify/ui-react";
    import "./App.css";
    import { Amplify } from "aws-amplify";
    import { Schema } from "../amplify/data/resource";
    import { generateClient } from "aws-amplify/data";
    import outputs from "../amplify_outputs.json";
    
    
    import "@aws-amplify/ui-react/styles.css";
    
    Amplify.configure(outputs);
    
    const amplifyClient = generateClient<Schema>({
      authMode: "userPool",
    });
    
    function App() {
      const [result, setResult] = useState<string>("");
      const [loading, setLoading] = useState(false);
    
      const onSubmit = async (event: FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        setLoading(true);
    
        try {
          const formData = new FormData(event.currentTarget);
          
          const { data, errors } = await amplifyClient.queries.askBedrock({
            ingredients: [formData.get("ingredients")?.toString() || ""],
          });
    
          if (!errors) {
            setResult(data?.body || "No data returned");
          } else {
            console.log(errors);
          }
    
      
        } catch (e) {
          alert(`An error occurred: ${e}`);
        } finally {
          setLoading(false);
        }
      };
    
      return (
        <div className="app-container">
          <div className="header-container">
            <h1 className="main-header">
              Meet Your Personal
              <br />
              <span className="highlight">Recipe AI</span>
            </h1>
            <p className="description">
              Simply type a few ingredients using the format ingredient1,
              ingredient2, etc., and Recipe AI will generate an all-new recipe on
              demand...
            </p>
          </div>
          <form onSubmit={onSubmit} className="form-container">
            <div className="search-container">
              <input
                type="text"
                className="wide-input"
                id="ingredients"
                name="ingredients"
                placeholder="Ingredient1, Ingredient2, Ingredient3,...etc"
              />
              <button type="submit" className="search-button">
                Generate
              </button>
            </div>
          </form>
          <div className="result-container">
            {loading ? (
              <div className="loader-container">
                <p>Loading...</p>
                <Loader size="large" />
                <Placeholder size="large" />
                <Placeholder size="large" />
                <Placeholder size="large" />
              </div>
            ) : (
              result && <p className="result">{result}</p>
            )}
          </div>
        </div>
      );
    }
    
    export default App;

    3.打开一个新的终端窗口,导航到项目根目录 (ai-recipe-generator),然后运行以下命令启动应用程序:  

    npm run dev

    4.选择 Local host 链接打开 Vite + React 应用程序。

    5.选择创建帐户选项卡,然后使用身份验证流程,输入电子邮件地址密码,创建新用户。然后选择创建账号

    6.验证码将发送到您的邮箱。输入验证码登录应用程序。

    7.登录后,您可以输入成分生成配方。 

    8.  在打开的终端窗口中,运行以下命令将更改推送到 GitHub: 

    git add .
    git commit -m 'connect to bedrock'
    git push origin main
    

    9.在新的浏览器窗口中登录 AWS 管理控制台,然后通过以下网址打开 AWS Amplify 控制台:https://console.aws.amazon.com/amplify/apps

    10.AWS Amplify 自动在 https://...amplifyapp.com 上构建您的源代码并部署您的应用程序,每次 git 推送都会更新您的部署实例。 选择访问已部署的 URL,即可查看您的 Web 应用程序的实时运行情况。

结论

现在,您已将应用程序连接到 Amplify 后端,并构建了一个前端,以根据用户提交的成分清单生成配方。

请就我们的表现提供反馈。