【05】从0到1构建AI生成思维导图应用 -- 前端交互实现

【05】从0到1构建AI生成思维导图应用 – 前端交互实现

大家好!最近自己做了一个完全免费的AI生成思维导图的网站,支持下载,编辑和对接微信公众号,可以在这里体验:https://lt2mind.zeabur.app/
上一章:https://blog.csdn.net/m0_56699208/article/details/140061215?spm=1001.2014.3001.5502

上一章中,我们已经构建了完整的 生成思维导图的 AI 功能,并将其暴露为 API。接下来,我们要编写一套交互逻辑,供用户输入文字或链接,点击按钮,即可生成思维导图,并提供下载和编辑按钮。

import axios from "axios";
export const toMind = async (query: string) => {
    const url = 'https://api.coze.cn/open_api/v2/chat';
    const headers = {
    'Content-Type': 'application/json',
      'Authorization': "Bearer your api key"
    };
    const body = {
      "conversation_id": "1",
      "bot_id": "your bot id",
      "user": "29032201862555",
      "query": query,
      "stream": false
    };
  
    try {
      const response = await axios.post(url, body, { headers });
      console.log('Response:', response.data.messages[2].content);
      const urlPattern = /https:\/\/[^\s]+/g;
      let urls = response.data.messages[2].content.match(urlPattern);
      let imgUrl = urls[0]
      let editUrl = urls[1]
      return {imgUrl, editUrl}
    } catch (error) {
      console.error('Error:', error);
    }
  };

这段代码使用正则表达式/https://[^\s]+/g来匹配响应内容中的URL,包含两个属性imgUrl和editUrl,分别对应匹配到的第一个和第二个URL。这两个URL分别是图片的下载地址和对应在treemind里面的编辑地址。我们只需要在前端把链接给到对应的按钮上,即可实现交互逻辑:
完整代码:

"use client";
import { useState } from "react";
import { SignedOut, useUser } from "@clerk/nextjs";
import { Textarea } from "./ui/textarea";
import Header from "./header";
import Feature from "../components/feature";
import Img from "next/image";
import { Button } from "@/components/ui/button";
import { toMind } from "@/lib/coze";
import Link from "next/link";
import { Typewriter } from "react-simple-typewriter";
import { Skeleton } from "@/components/ui/skeleton";
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "../components/ui/tooltip";

export default function Hero() {
  const { isSignedIn } = useUser();
  const [imgUrl, setImgUrl] = useState("");
  const [editUrl, setEditUrl] = useState("");
  const [loading, setLoading] = useState(false);

  const handleSubmit = async (event: any) => {
    event.preventDefault(); // Prevent the default form submission behavior
    if (!isSignedIn) {
      //router.push('/sign-in');
      return;
    }
    setLoading(true);
    const inputValue = event.target.elements.textOrLink.value; // Get the value from the textarea
    const result = await toMind(inputValue); // Call the toMind function with the input value
    if (result) {
      setImgUrl(result.imgUrl);
      setEditUrl(result.editUrl);
    }
    setLoading(false);
  };

  return (
    <div className="flex flex-col bg">
      <header className="text-blue-500">
        <Header />
        <section className="container max-w-5xl px-4 md:px-6 py-6 md:py-10">
          <div className="text-center space-y-4 sm:mt-4">
            <h1 className="text-4xl md:text-6xl font-bold tracking-widest">
              LT2MIND
            </h1>
            <p className="text-lg md:text-xl max-w-3xl mx-auto italic">
              <Typewriter
                words={[
                  "Transform your text and links into beautiful mind maps with ease.",
                ]}
                loop={1}
                cursor
                cursorStyle=""
                typeSpeed={20}
                deleteSpeed={50}
                delaySpeed={1000}
              />
            </p>
          </div>
        </section>
        <Feature />
        <section className="py-12 md:py-20">
          <div className="container max-w-5xl px-4 md:px-6 grid grid-cols-1 md:grid-cols-2 gap-8">
            <div className="space-y-4">
              <h2 className="text-3xl font-bold text-purple-400">
                Convert to Mind Map
              </h2>
              <p className="text-muted-foreground">
                Enter your text or link and let LT2Mind do the rest. You may
                wait for one minute or more for the transition to complete.
              </p>
              <form className="flex gap-2" onSubmit={handleSubmit}>
                <div className="flex flex-col gap-2 h-[40vh] w-full">
                  <Textarea
                    name="textOrLink"
                    placeholder="Enter text or link..."
                    className="shadow-sm focus:border-none flex-1 resize-none bg"
                    style={{
                      outline: "none",
                      overflow: "auto",
                      scrollbarWidth: "none",
                      msOverflowStyle: "none",
                    }}
                  />

                  <style jsx>{`
                    textarea::-webkit-scrollbar {
                      display: none;
                    }
                  `}</style>
                  <TooltipProvider>
                    <Tooltip>
                      <TooltipTrigger asChild>
                        <div>
                          <Button
                            type="submit"
                            className="mt-2 w-full bg-pink-200 text-purple-500 hover:bg-pink-100"
                            disabled={!isSignedIn}
                          >
                            Convert
                          </Button>
                        </div>
                      </TooltipTrigger>
                      {!isSignedIn && (
                        <TooltipContent>
                          You need to sign in to convert
                        </TooltipContent>
                      )}
                    </Tooltip>
                  </TooltipProvider>
                </div>
              </form>
            </div>
            {loading ? (
              <div className="flex flex-col items-center justify-center gap-2">
                <div className="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-purple-500"></div>
                <p className="text-lg text-purple-400">converting...</p>
              </div>
            ) : imgUrl ? (
              <div className="flex flex-col items-center justify-center gap-2">
                <img
                  src={imgUrl}
                  alt="Image 1"
                  className="w-full h-full object-contain shadow-sm"
                />
                <div className="flex gap-x-4 w-full justify-center">
                  <Link href={editUrl} target="_blank" className="w-full">
                    <Button className="bg-pink-200 text-purple-500 w-full hover:bg-pink-100">
                      Edit in TreeMind
                    </Button>
                  </Link>
                  <a
                    href={imgUrl}
                    download="mindmap.jpeg"
                    target="_blank"
                    className="w-full"
                  >
                    <Button className="bg-pink-200 text-purple-500 w-full hover:bg-pink-100">
                      Download
                    </Button>
                  </a>
                </div>
              </div>
            ) : (
              <div className="flex flex-col items-center justify-center gap-2">
                <p className="text-lg text-purple-400">
                  Waiting For Conversion
                  <Typewriter
                    words={["..."]}
                    loop={true}
                    cursor
                    cursorStyle=""
                    typeSpeed={200}
                    deleteSpeed={50}
                    delaySpeed={2000}
                  />
                </p>
                {/* <div className="flex gap-x-4 w-full justify-center">
                <Skeleton className="w-full" />
                <Skeleton className="w-full" />
                </div> */}
              </div>
            )}
          </div>
        </section>
      </header>
    </div>
  );
}

这样,用户输入文字,点击按钮后,就能实现生成的逻辑:
在这里插入图片描述
在这里插入图片描述
生成完成后,用户可以点击按钮选择下载或是继续编辑。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/757786.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++】初识C++(一)

一.什么是C C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的程序&#xff0c;需要高度 的抽象和建模时&#xff0c;C语言则不合适。为了解决软件危机&#xff0c; 20世纪80年代&#xff0c; 计算机界提出了OOP(object o…

Mathematica训练课(46)-- 一些常用的画图函数

在前面的课程中&#xff0c;我们已经梳理了Plot的画图用法&#xff0c;今天就详细梳理一下其他的画图函数用法&#xff1b; 1. 画一条直线 2. Circle(圆) 3. Disk&#xff08;圆盘&#xff09; 4. 画出一个矩形 5. 箭头

itext生成pdf文件demo示例

需求 在PDF文件中植入一些信息&#xff08;pdf模版&#xff09; 制作模版 可以看到下面红色箭头标注位置&#xff0c;这都是我们需要动态写入数据的表单域&#xff0c;可以使用wps等工具来制作 点击编辑表单&#xff0c;可以给对应空间添加表单域&#xff0c;表单域名称是ke…

ic基础|功耗篇04:门级低功耗技术

大家好&#xff0c;我是数字小熊饼干&#xff0c;一个练习时长两年半的IC打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结&#xff0c;并通过汇总成文章的形式进行输出&#xff0c;相信无论你是在职的还是…

UE5材质之HLSL:深度

UE4/5的Custom节点&#xff1a;在VScode使用HLSL&#xff08;新手入门用&#xff09;_vscode写hlsl-CSDN博客 效果&#xff1a; 材质节点&#xff1a; 自定义节点代码&#xff1a; float3 rayStepViewDir*-1; float4 inputTexTexture2DSample(TexObject,TexObjectSampler,uv)…

AGPT•intelligence:带你领略全新量化交易的风采

随着金融科技的快速发展&#xff0c;量化交易已经成为了投资领域的热门话题。越来越多的投资者开始关注和使用量化交易软件来进行投资决策。在市场上有许多量化交易软件可供选择。 Delaek&#xff0c;是一位资深的金融科技专家&#xff0c;在 2020年成立一家专注于数字资产量化…

【第三方JSON库】org.json.simple用法初探—Java编程【Eclipse平台】【不使用项目管理工具】【不添加依赖解析】

本文将重点介绍&#xff0c;在不使用项目管理工具&#xff0c;不添加依赖解析情况下&#xff0c;【第三方库】JSON.simple库在Java编程的应用。 JSON.simple是一种由纯java开发的开源JSON库&#xff0c;包含在JSON.simple.jar中。它提供了一种简单的方式来处理JSON数据和以JSO…

计算机类主题会议推荐之——AIIIP 2024

【ACM出版 |IEEE&ACM院士、CCF杰出会员担任组委| 往届会后4个月检索 】 第三届人工智能与智能信息处理国际学术会议&#xff08;AIIIP 2024&#xff09; 2024 3rd International Conference on Artificial Intelligence and Intelligent Information Processing 中国-天…

QT QSlider控件-主介绍 触发函数常用函数

QSlider控件是Qt库中用于提供一个可拖动滑块以选择数值或范围的界面元素。它广泛应用于需要用户进行数值调节的场景&#xff0c;如音量控制、亮度调整等。 一、QAbstractSlider的6个信号量触发函数&#xff1a; 1、void actionTriggered (int action): 当滑块上的某个可定义动…

EXCEL 复制后转置粘贴

nodepad 转置参考&#xff1a; https://editor.csdn.net/md/?articleId140014651 1. WPS复制后转置粘贴 复制-》右键-》顶部第一行-》粘贴行列转置&#xff0c;如下图&#xff1a; 2. Excel office365 本地版 2. Excel office365 在线版

module java.base does not “opens java.lang“ to unnamed module

目录 原因&#xff1a;解决方法&#xff1a;方法一&#xff1a;方法二&#xff1a;方法三&#xff1a; SpringBoot项目运行报如下错误 Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.def…

关于组织赴俄罗斯(莫斯科)第 28 届国际汽车零部件、汽车维修设备和商品展览会商务考察的通知

关于组织赴俄罗斯&#xff08;莫斯科&#xff09; 第 28 届国际汽车零部件、汽车维修设备和商品展览会商务考察的通知 展会名称&#xff1a;俄罗斯&#xff08;莫斯科&#xff09;第 28 届国际汽车零部件、汽车零部件、汽车维修设备和商品展览会 时间&#xff1a;2024 年 8 月…

仓库管理系统19--盘存管理

原创不易&#xff0c;打字不易&#xff0c;截图不易&#xff0c;多多点赞&#xff0c;送人玫瑰&#xff0c;留有余香&#xff0c;财务自由明日实现 1、什么是盘存 盘存也叫盘库&#xff0c;盘库是指对一个仓库、库房或者商店的库存进行全面清点和核对的过程。在盘库过程中&am…

解决403 Forbidden错误的全面指南,快速解决403 Forbidden错误

在浏览互联网时&#xff0c;遭遇到“403 Forbidden”错误可以说是既常见又令人困惑。这个错误提示通常意味着服务器理解请求但拒绝授权访问。尽管它可能看起来让人无从下手&#xff0c;但通过一些方法通常可以找到原因并解决这个问题。 什么是403 Forbidden错误&#xff1f; “…

小到微妙:少女微笑

一、妙与不妙&#xff0c;少女与微笑 我们曾经解过汉字“妙”&#xff0c;妙字可以拆分为少女二字&#xff0c;即&#xff1a; 妙 女 少 少女 但这&#xff0c;其实并没有对 “妙”字 完成完整性解析&#xff0c;如果要完成完整性的说明&#xff0c;应当加上微笑&#xff0…

1、Python编程入门:从硬件基础到解释器类型

Python是一种免费、开源、跨平台、动态、面向对象的编程语言。它以其简洁易读的语法和强大的功能而闻名&#xff0c;广泛应用于各种领域&#xff0c;如Web开发、数据分析、人工智能等。本文将介绍Python的基本概念、执行方式以及常用的Linux命令&#xff0c;帮助初学者快速入门…

Ascend基于自定义算子工程的算子开发

环境准备 见https://gitee.com/zaj1414904389/ascend-tutorial.git 工程创建 CANN软件包中提供了工程创建工具msopgen&#xff0c;开发者可以输入算子原型定义文件生成Ascend C算子开发工程 [{"op": "AddCustom","input_desc": [{"name…

Java的NIO体系

目录 NIO1、操作系统级别下的IO模型有哪些&#xff1f;2、Java语言下的IO模型有哪些&#xff1f;3、Java的NIO应用场景&#xff1f;相比于IO的优势在哪&#xff1f;4、Java的IO、NIO、AIO 操作文件读写5、NIO的核心类 :Buffer&#xff08;缓冲区&#xff09;、Channel&#xff…

版本控制系统:Git 纯应用(持续更新)

基本操作 ctrl上行键&#xff1a;上次代码 本地仓库&#xff1a;Git init 新建文件&#xff1a;touch xxxx.xxx 查看状态&#xff1a;Git status 文件从工作区——暂存区&#xff1a;Git add ./文件名(.是通配符代表所有) 暂存区——仓库&#xff1a;Git commit -m &…

如何利用ChatGPT改善日常生活:一个普通人的指南

当你打开 ChatGPT&#xff0c;显现的是一个简洁的聊天界面。 许多人利用 ChatGPT 进行日常对话。 然而&#xff0c;ChatGPT 的功能远不止于此。 对话只是其众多能力中的一种&#xff0c;如果仅将其视为高级版的聊天机器人&#xff0c;那未免低估了它。 AI 在信息处理方面的…