【Next.js 项目实战系列】05-删除 Issue

原文链接

CSDN 的排版/样式可能有问题,去我的博客查看原文系列吧,觉得有用的话,给我的库点个star,关注一下吧 

上一篇【Next.js 项目实战系列】04-修改 Issue

删除 Issue

添加删除 Button​

本节代码链接

这里我们主要关注布局的问题,我们调整 Grid 的 columns 与第一个 Box 的设置,使得在小设备上,两个 Box 上下排布,在中等及以上,左边 Box 占屏幕 80%

# /app/issues/[id]/page.tsxconst IssueDeatilPage = async ({ params }: Props) => {...return (
+     <Grid columns={{ initial: "1", sm: "5" }} gap="5">
+       <Box className="md:col-span-4"><IssueDetails issue={issue} /></Box><Box><Flex direction="column" gap="3"><EditIssueButton issueId={issue.id} />
+           <DeleteIssueButton issueId={issue.id} /></Flex></Box></Grid>);};export default IssueDeatilPage;

其次,在 layout.tsx 中将 <main > 中所有内容用 Radix UI 中的 Container 包起来,以实现居中,最终显示效果如下

Delete Page

添加确认框​

本节代码链接

# /app/issues/[id]/DeleteIssueButton.tsx"use client";
import { AlertDialog, Button, Flex } from "@radix-ui/themes";
import { Cross2Icon } from "@radix-ui/react-icons";const DeleteIssueButton = ({ issueId }: { issueId: number }) => {return (<AlertDialog.Root><AlertDialog.Trigger><Button color="red"><Cross2Icon />Delete Issue</Button></AlertDialog.Trigger><AlertDialog.Content><AlertDialog.Title>Confirm Deletion</AlertDialog.Title><AlertDialog.Description>Are you sure you want to delete this? This action cannot be undone.</AlertDialog.Description><Flex mt="4" gap="4"><AlertDialog.Cancel><Button variant="soft" color="gray">Cancel</Button></AlertDialog.Cancel><AlertDialog.Action><Button color="red">Delete Issue</Button></AlertDialog.Action></Flex></AlertDialog.Content></AlertDialog.Root>);
};
export default DeleteIssueButton;

显示效果如下

Confirm Dialog

删除 Issue​

API​

本节代码链接

# /app/api/issues/[id]/route.tsxexport async function DELETE(request: NextRequest,{ params }: { params: { id: string } }
) {const issue = await prisma.issue.findUnique({where: { id: parseInt(params.id) },});if (!issue)return NextResponse.json({ error: "Invalid Issue" }, { status: 404 });await prisma.issue.delete({where: { id: issue.id },});return NextResponse.json({ status: 200 });
}

连接​

本节代码链接

# /app/issues/[id]/DeleteIssueButton.tsx...
+ import axios from "axios";
+ import { useRouter } from "next/navigation";const DeleteIssueButton = ({ issueId }: { issueId: number }) => {
+   const router = useRouter();
+   const handleDelete = async () => {
+     await axios.delete("/api/issues/" + issueId);
+     router.push("/issues");
+     router.refresh();
+   };return (...<AlertDialog.Action>
+       <Button color="red" onClick={handleDelete}>Delete Issue</Button></AlertDialog.Action>...);};export default DeleteIssueButton;

处理 error​

本节代码链接

# /app/issues/[id]/DeleteIssueButton.tsx...
+ import { useState } from "react";const DeleteIssueButton = ({ issueId }: { issueId: number }) => {
+   const [error, setError] = useState(false);const handleDeleteIssue = async () => {try {await axios.delete("/api/issues/" + issueId);router.push("/issues");router.refresh();} catch (error) {
+       setError(true);}};return (<><AlertDialog.Root>...</AlertDialog.Root>
+       <AlertDialog.Root open={error}>
+         <AlertDialog.Content>
+           <AlertDialog.Title>Error</AlertDialog.Title>
+           <AlertDialog.Description>
+             This issue could not be deleted
+           </AlertDialog.Description>
+           <Button
+             color="gray"
+             variant="soft"
+             mt="4"
+             onClick={() => setError(false)}
+           >
+             OK
+           </Button>
+         </AlertDialog.Content>
+       </AlertDialog.Root></>);};export default DeleteIssueButton;

效果如下,在发生错误时会弹出这样一个框

Delete Error

优化用户体验​

本节代码链接

和Button 优化技巧一章相同,我们可以添加一个 Spinner 和 Disable 来优化用户体验

# /app/issues/[id]/DeleteIssueButton.tsx+ import { Spinner } from "@/app/components";const DeleteIssueButton = ({ issueId }: { issueId: number }) => {
+   const [isDeleting, setDeleting] = useState(false);const handleDeleteIssue = async () => {try {
+       setDeleting(true);await axios.delete("/api/issues/" + issueId);router.push("/issues");router.refresh();} catch (error) {
+       setDeleting(false);setError(true);}};return (...<AlertDialog.Trigger>
+       <Button color="red" disabled={isDeleting}><Cross2Icon />Delete Issue
+         {isDeleting && <Spinner />}</Button></AlertDialog.Trigger>...);};export default DeleteIssueButton;

CSDN 的排版/样式可能有问题,去我的博客查看原文系列吧,觉得有用的话,给我的库点个star,关注一下吧  

 下一篇讲身份验证

【Next.js 项目实战系列】06-身份验证

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ANSYS Workbench纤维混凝土3D

在ANSYS Workbench建立三维纤维混凝土模型可采用CAD随机几何3D插件建模后导入&#xff0c;模型包含球体粗骨料、圆柱体长纤维、水泥砂浆基体等不同组分。 在CAD随机几何3D插件内设置模型参数后运行&#xff0c;即可在AutoCAD内建立三维纤维混凝土模型&#xff0c;插件支持任意…

uniapp,获取头部高度

头部自定义时候&#xff0c;设置获取安全区域&#xff0c;可以用 uni.getSystemInfoSync();接口。 <view class"statusBar" :style"{height:statusBarHeightpx}"> let SYSuni.getSystemInfoSync(); let statusBarHeightref(SYS.statusBarHeight) …

Linux中如何理解一切皆文件

根据之前的学习我们会有一些少许的疑惑&#xff0c;我们的stdin &#xff0c;stdout&#xff0c;stderr访问的是键盘显示器&#xff0c;然而键盘显示器等他们都有一个共同的特点就是他们都是外设&#xff0c;那么这些外设是怎么被看成是文件的呢&#xff1f; 看图可以知道硬件的…

Qt自定义一个圆角对话框

如何得到一个圆角对话框&#xff1f; 步骤&#xff1a; 1、继承自QDiaglog 2、去掉系统自带的边框 3、设置背景透明,不设置4个角会有多余的部分出现颜色 4、对话框内部添加1个QWidget&#xff0c;给这个widget设置圆角&#xff0c;并添加到布局中让他充满对话框 5、后续对…

Cheat Engine v7.1 修改百度网盘无限速下载(修改方法在网盘内)

下载&#xff1a;https://pan.quark.cn/s/a9d8fd8eaccc 这些年为了免费“化解”百度网盘限速问题&#xff0c;网络上可谓层出不穷的出现各种不限速功能软件&#xff0c;比如前不久给大家分享过的万能联播就是其中之一。 万能联播还可以&#xff0c;也算是百度自家产品&#x…

Notepad++将搜索内容所在行选中,并进行复制等操作

背景 Notepad在非常多的数据行内容中&#xff0c;按照指定内容检索&#xff0c;并定位到具体行&#xff0c;而后对内容行的数据进行复制、剪切、删除等处理动作。 操作说明 检索并标记所在行 弹出搜索框&#xff1a;按下 Ctrl F。 输入查找字符串&#xff1a;在搜索框中输入要…

【目标检测论文解读复现NO.39】基于改进 YOLOv8 的轻量级复杂环境苹果叶片病害检测方法

前言 此前出了目标改进算法专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读最新目标检测算法论文&#xff0c…

免费开源Odoo软件如何实现电商仓库高效发货

世界排名第一的免费开源ERP软件Odoo&#xff0c;拥有非常强大的仓库管理WMS功能。本文以电商仓库发货管理为例&#xff0c;介绍电商订单的仓库发货作业的各种方法。电商订单仓库发货流程&#xff0c;通常分为三个步骤&#xff0c;即拣货、打包、发货。根据仓库日处理订单数量的…

【C++打怪之路Lv11】-- stack、queue和优先级队列

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;重生之我在学Linux&#xff0c;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持…

RabbitMQ进阶_可靠性

文章目录 一、 发送者的可靠性1.1、 生产者重试机制1.2、 生产者确认机制1.2.1、确认机制理论1.2.2、确认机制实现1.2.2.1、定义ReturnCallback1.2.2.2、定义ConfirmCallback 二、 MQ的可靠性2.1、 数据持久化2.1.1、 交换机持久化2.1.2、 队列持久化2.1.3、 消息持久化 2.2、 …

《使用Gin框架构建分布式应用》阅读笔记:p88-p100

《用Gin框架构建分布式应用》学习第6天&#xff0c;p88-p100总结&#xff0c;总计13页。 一、技术总结 1.MongoDB CRUD操作 (1)InsertOne(), InsertMany() (2)Find() (3)UpdateOne, UpdateMany() (4)DeleteOne(), DeleteMany() 2.MongoDB primitive p96&#xff0c;rec…

记录:网鼎杯2024赛前热身WEB01

目录扫描&#xff0c;发现上传点&#xff0c;判断可能存在文件上传漏洞&#xff0c;并根据文件后缀判断网站开发语言为php 编写蚁剑一句话木马直接上传 蚁剑连接 这里生成 的flag是随机的&#xff0c;因为烽火台反作弊会随机生成环境&#xff0c;在一顿查找后&#xff0c;在hom…

复旦大学全球供应链研究中心揭牌,合合信息共话大数据赋能

10月13日&#xff0c;复旦大学全球供应链研究中心&#xff08;以下简称“中心”&#xff09;揭牌仪式在复旦大学管理学院政立院区隆重举行。我国的供应链体系庞大复杂&#xff0c;在百年未有之大变局下&#xff0c;保障产业链供应链安全已成为我国的重要战略目标。中心的设立旨…

九、pico+Unity交互开发——触碰抓取

一、VR交互的类型 Hover&#xff08;悬停&#xff09; 定义&#xff1a;发起交互的对象停留在可交互对象的交互区域。例如&#xff0c;当手触摸到物品表面&#xff08;可交互区域&#xff09;时&#xff0c;视为触发了Hover。 Grab&#xff08;抓取&#xff09; 概念&#xff…

张雪峰:如果你现在是计算机专业,一定要优先报网络安全,它是未来国家发展的大方向

&#x1f91f; 基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 前言 “计算机专业 一定要优先报 网络安全 它是未来国家发展的大方向” 为什么推荐学网络安全&#xff1f; “没有网络安全就没有国家安全。”当前&#xff…

优化UVM环境(九)-将interface文件放在env pkg外面

书接上回&#xff1a; 优化UVM环境&#xff08;八&#xff09;-整理project_common_pkg文件 My_env_pkg.sv里不能包含interface&#xff0c;需要将my_intf.sv文件放在pkg之外

使用飞桨AI Studio平台训练数据,并进行图像识别分析得牡丹花测试

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

【Qt】控件——Qt多元素控件、常见的多元素控件、多元素控件的使用、List Widget、Table Widget、Tree Widget

文章目录 QtQt多元素控件List WidgetTable WidgetTree Widget Qt Qt多元素控件 List Widget 使用 QListWidget 能够显示一个纵向的列表。 属性说明currentRow当前被选中的是第几行。count一共有多少行。sortingEnabled是否允许排序。isWrapping是否允许换行。itemAlignment元素…

【vue 封装一个select组件】封装一个select组件,包括select样式的修改,以及解决select,onchange事件失效问题

实现效果:封装一个下拉菜单组件,效果如下图 父组件代码如下: 子组件代码: <template><div><form><select name="languages" id="lang" ><option :value="item.value" v-for="item in optionList" >…

【火山引擎】语音合成 | HTTP接口 | 一次性合成 | python

目录 一 准备工作 二 HTTP接口(一次性合成-非流式) 1 接口说明 2 身份认证 3 请求方式 三 实践 四 注意事项 火山引擎语音合成TTS(Text-to-Speech)是一种基于云计算的语音合成服务,可以将文本转化为自然、流畅的语音。以下是火山引擎TTS的主要功能和特点: ①多种语音…