【React】(推荐项目)一个用 React 构建的 CRUD 应用程序

news2024/9/21 14:08:01

推荐项目:CRUD 应用示例

在本篇文章中,我想向大家推荐一个非常实用的项目:CRUD 应用示例。这个项目展示了如何使用现代技术栈创建一个基础的增删改查(CRUD)应用,非常适合用于学习和实践后端开发技能。

适用场景

通过这个示例,您可以掌握 CRUD 操作的完整流程,并了解如何将前后端整合在一起构建一个完整的应用。

无论您是后端开发新手,还是希望进一步巩固自己的开发技能,这个项目都可以作为一个很好的参考示例。

项目链接

GitHub 项目地址:https://github.com/SafdarJamal/crud-app

项目截图

  • 登录界面
    在这里插入图片描述
  • 主页
    在这里插入图片描述
  • 编辑界面

在这里插入图片描述

部分代码

  • 登录
import React, { useState } from 'react';
import Swal from 'sweetalert2';

const Login = ({ setIsAuthenticated }) => {
  const adminEmail = 'admin@example.com';
  const adminPassword = 'qwerty';

  const [email, setEmail] = useState('admin@example.com');
  const [password, setPassword] = useState('qwerty');

  const handleLogin = e => {
    e.preventDefault();

    if (email === adminEmail && password === adminPassword) {
      Swal.fire({
        timer: 1500,
        showConfirmButton: false,
        willOpen: () => {
          Swal.showLoading();
        },
        willClose: () => {
          localStorage.setItem('is_authenticated', true);
          setIsAuthenticated(true);

          Swal.fire({
            icon: 'success',
            title: 'Successfully logged in!',
            showConfirmButton: false,
            timer: 1500,
          });
        },
      });
    } else {
      Swal.fire({
        timer: 1500,
        showConfirmButton: false,
        willOpen: () => {
          Swal.showLoading();
        },
        willClose: () => {
          Swal.fire({
            icon: 'error',
            title: 'Error!',
            text: 'Incorrect email or password.',
            showConfirmButton: true,
          });
        },
      });
    }
  };

  return (
    <div className="small-container">
      <form onSubmit={handleLogin}>
        <h1>Admin Login</h1>
        <label htmlFor="email">Email</label>
        <input
          id="email"
          type="email"
          name="email"
          placeholder="admin@example.com"
          value={email}
          onChange={e => setEmail(e.target.value)}
        />
        <label htmlFor="password">Password</label>
        <input
          id="password"
          type="password"
          name="password"
          placeholder="qwerty"
          value={password}
          onChange={e => setPassword(e.target.value)}
        />
        <input style={{ marginTop: '12px' }} type="submit" value="Login" />
      </form>
    </div>
  );
};

export default Login;

  • 主页
import React, { useState, useEffect } from 'react';
import Swal from 'sweetalert2';

import Header from './Header';
import Table from './Table';
import Add from './Add';
import Edit from './Edit';

import { employeesData } from '../../data';

const Dashboard = ({ setIsAuthenticated }) => {
  const [employees, setEmployees] = useState(employeesData);
  const [selectedEmployee, setSelectedEmployee] = useState(null);
  const [isAdding, setIsAdding] = useState(false);
  const [isEditing, setIsEditing] = useState(false);

  useEffect(() => {
    const data = JSON.parse(localStorage.getItem('employees_data'));
    if (data !== null && Object.keys(data).length !== 0) setEmployees(data);
  }, []);

  const handleEdit = id => {
    const [employee] = employees.filter(employee => employee.id === id);

    setSelectedEmployee(employee);
    setIsEditing(true);
  };

  const handleDelete = id => {
    Swal.fire({
      icon: 'warning',
      title: 'Are you sure?',
      text: "You won't be able to revert this!",
      showCancelButton: true,
      confirmButtonText: 'Yes, delete it!',
      cancelButtonText: 'No, cancel!',
    }).then(result => {
      if (result.value) {
        const [employee] = employees.filter(employee => employee.id === id);

        Swal.fire({
          icon: 'success',
          title: 'Deleted!',
          text: `${employee.firstName} ${employee.lastName}'s data has been deleted.`,
          showConfirmButton: false,
          timer: 1500,
        });

        const employeesCopy = employees.filter(employee => employee.id !== id);
        localStorage.setItem('employees_data', JSON.stringify(employeesCopy));
        setEmployees(employeesCopy);
      }
    });
  };

  return (
    <div className="container">
      {!isAdding && !isEditing && (
        <>
          <Header
            setIsAdding={setIsAdding}
            setIsAuthenticated={setIsAuthenticated}
          />
          <Table
            employees={employees}
            handleEdit={handleEdit}
            handleDelete={handleDelete}
          />
        </>
      )}
      {isAdding && (
        <Add
          employees={employees}
          setEmployees={setEmployees}
          setIsAdding={setIsAdding}
        />
      )}
      {isEditing && (
        <Edit
          employees={employees}
          selectedEmployee={selectedEmployee}
          setEmployees={setEmployees}
          setIsEditing={setIsEditing}
        />
      )}
    </div>
  );
};

export default Dashboard;


如果你觉得这篇文章对你有帮助,别忘了点赞和关注,更多技术干货敬请期待!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【工具变量】科技金融试点城市DID数据集(2000-2023年)

时间跨度&#xff1a;2000-2023年数据范围&#xff1a;286个地级市包含指标&#xff1a; year city treat post DID&#xff08;treat*post&#xff09; 样例数据&#xff1a; 包含内容&#xff1a; 全部内容下载链接&#xff1a; 参考文献-pdf格式&#xff1a;https://…

Navicat连接SQLServer报错

一、Navicat连接SQLServer报错 1.1、问题描述 由于项目原因&#xff0c;需要使用SQLServer作为数据源。Navicat中新建SQLServer的连接&#xff0c;填写完必要信息后连接失败&#xff0c;报错原因如下&#xff1a; 1.2、Navicat的版本 1.3、解决方法 第一步&#xff1a;下载【s…

工厂模式,策略模式,代理模式,单例模式在项目中的应用

项目背景&#xff1a; 首先这篇文章是总结了OJ项目和AI答题平台项目&#xff08;和一点点的聚合搜索项目&#xff09;中设计模式的文章 在项目中也用了很多次的设计模式&#xff0c;我感觉起来&#xff0c;这些设计模式的作用就是提高项目的扩展性和降低耦合性 工厂模式&…

Gitlab学习(007 gitlab项目操作)

尚硅谷2024最新Git企业实战教程&#xff0c;全方位学习git与gitlab 总时长 5:42:00 共40P 此文章包含第25p-第p26的内容 文章目录 推送项目到gitlabidea安装gitlab插件配置免密登录推送项目到远程库 在gitlab上创建项目额外功能的使用推送分支到远程库标记功能创建合并请求 推…

leetcode刷题(71-75)

算法是码农的基本功&#xff0c;也是各个大厂必考察的重点&#xff0c;让我们一起坚持写题吧。 遇事不决&#xff0c;可问春风&#xff0c;春风不语&#xff0c;即是本心。 我们在我们能力范围内&#xff0c;做好我们该做的事&#xff0c;然后相信一切都事最好的安排就可以啦…

IM项目组件学习-----spdlog二次封装

这里写自定义目录标题 封装的原因封装的思想初始化接口的封装对日志输出接口进行宏的封装 封装的原因 1.避免单例的锁冲突&#xff0c;因此直接创建全局的线程安全的日志器进行使用 2.因为日志输出没有文件名行号&#xff0c;因此使用宏进行二次封装输出日志的文件名和行号 3.…

【shell脚本1】Shell脚本学习--入门

目录 简介 Hello World 注释 打印输出 简介 Shell是一种脚本语言&#xff0c;那么&#xff0c;就必须有解释器来执行这些脚本。 Unix/Linux上常见的Shell脚本解释器有bash、sh、csh、ksh等&#xff0c;习惯上把它们称作一种Shell。我们常说有多少种Shell&#xff0c;其实说的…

昇腾大模型推理解决方案MindIE部署

MindIE大模型推理套件 MindIE&#xff08;Mind Inference Engine&#xff0c;昇腾推理引擎&#xff09;是华为公司针对AI全场景推出的整体解决方案&#xff0c;包含丰富的推理加速套件。通过开放各层次AI能力&#xff0c;支撑客户多样化的AI业务需求&#xff0c;使能百模千态&a…

Windows快捷切换Java jdk版本

使用方法 新建txt文本文件&#xff0c;将下方代码粘贴进去编辑对应的jdk路径 如&#xff1a;set JAVA_HOMED:\Java\jdk-17.0.11修改文件后缀为bat&#xff0c;双击运行选择对应版本 echo off rem 切换Java jdk版本 echo 请以管理员来进行切换 java -version:menu echo echo 请…

2024华为杯C题详细完整思路和视频讲解

文章目录 一、背景问题描述数据描述问题问题一&#xff1a; 励磁波形分类问题二&#xff1a; 斯坦麦茨方程&#xff08;Steinmetz-equation&#xff09;修正问题三&#xff1a; 磁芯损耗因素分析问题四问题五 参考文献补充磁芯损耗分离模型磁芯损耗经验计算模型 特别注意事项问…

【Android Studio】2024.1.1最新版本AS调试老项目(老版AS项目文件、旧gradle)导入其他人的项目

文章目录 实验环境开始修改项目文件1. 删除.gradle及.idea两个文件夹2.修改SDK路径&#xff08;本地SDK存放路径&#xff09;3.修改gradle版本4.修改gradle插件版本&#xff08;AGP&#xff09;5.修改JDK版本 实验环境 Android Studio 版本 项目版本 开始修改项目文件 1. 删…

我的AI工具箱Tauri版-MicrosoftTTS文本转语音

本教程基于自研的AI工具箱Tauri版进行MicrosoftTTS文本转语音服务。 MicrosoftTTS文本转语音服务 是自研的AI工具箱Tauri版中的一款功能模块&#xff0c;专为实现高效的文本转语音操作而设计。通过集成微软TTS服务&#xff0c;用户可以将大量文本自动转换为自然流畅的语音文件…

创新驱动,技术引领:2025年广州见证汽车电子技术新高度

汽车行业的创新浪潮正汹涌澎湃&#xff0c;一场引领未来出行的科技盛宴即将拉开帷幕&#xff01; AUTO TECH 2025 第十二届广州国际汽车电子技术展览会将于 2025 年 11 月 20日至 22 日在广州保利世贸博览馆&#xff08;PWTC Expo&#xff09;隆重举行。 作为亚洲地区领先的汽…

树莓派智能语音助手实现音乐播放

树莓派语音助手从诞生的第一天开始&#xff0c;我就想着让它能像小爱音箱一样&#xff0c;可以语音控制播放音乐。经过这些日子的倒腾&#xff0c;今天终于实现了。 接下里&#xff0c;和大家分享下我的实现方法&#xff1a;首先音乐播放模块用的是我在上一篇博文写的《用sound…

netty编程之基于websocket发送二进制数据

写在前面 本文看下基于websocket发送二进制数据。 1&#xff1a;正文 直接看源码吧&#xff0c;主要如下几个类&#xff1a; WebSocketServerProtocolHandler (内置)&#xff1a;负责websocket握手消息处理 BinaryWebSocketFrameHandler(自定义)&#xff1a;负责处理二进制…

【深入理解SpringCloud微服务】了解微服务的熔断、限流、降级,手写实现一个微服务熔断限流器

【深入理解SpringCloud微服务】了解微服务的熔断、限流、降级&#xff0c;手写实现一个微服务熔断限流器 服务雪崩熔断、限流、降级熔断降级限流 手写实现一个微服务熔断限流器架构设计代码实现整体逻辑ProtectorAspect#aroundMethod(ProceedingJoinPoint)具体实现1、获取接口对…

在 Windows 上运行 Vue 项目时解决 ‘NODE_OPTIONS‘ 错误

在 Windows 上运行 Vue 项目时解决 ‘NODE_OPTIONS’ 错误 在 Windows 系统上启动 Vue 项目时&#xff0c;遭遇报错。具体报错信息如下&#xff1a; ‘NODE_OPTIONS‘ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。这个错误通常意味着 Windows 系统无法识…

速通LLaMA2:《Llama 2: Open Foundation and Fine-Tuned Chat Models》全文解读

文章目录 概览LLaMA和LLaMA2的区别AbstractIntroductionPretrainingFine-tuning1. 概括2、Supervised Fine-Tuning&#xff08;SFT&#xff09;3、⭐Reinforcement Learning with Human Feedback&#xff08;RLHF&#xff09;&#x1f53a;总览Training Objectives&#xff1a;…

Redis——redispluspls库——通用命令以及String类型相关接口使用

文章目录 通用命令get&#xff0c;setkeys插入迭代器 expire和ttltype string 类型接口set和getset NX和XXmset 和 mgetgetrange 和 setrangeincr 和 decr 通用命令 get&#xff0c;set void get_set_test(sw::redis::Redis& redis){//bool set(const sw::redis::StringV…

回归预测 | Matlab实现INFO-HKELM向量加权算法优化混合核极限学习机多变量回归预测

回归预测 | Matlab实现INFO-HKELM向量加权算法优化混合核极限学习机多变量回归预测 目录 回归预测 | Matlab实现INFO-HKELM向量加权算法优化混合核极限学习机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现INFO-HKELM向量加权算法优化混合核极…