Crud, react Js (Front-end), .Net 6 (Back-end) Banco SqLServer
Criar em qualquer vers?o mais ressente do microsoft Sql Server um banco de dados conforme a figura acima.
Vamos utilizar o visual studio para constru??o da Api Back-end e visual code para o front-end.
N?o irei entrar em detalhes sobre o que cada comando faz, mais podem conferir aqui nesse link para o back-end https://learn.microsoft.com/en-us/dotnet/ , https://learn.microsoft.com/pt-br/training/dotnet/ e para o front-end https://pt-br.reactjs.org/ esses link′s é possível entender e aprender o que cada comando faz.
Crie uma tabela no banco de dados conforme a figura abaixo.
N?o esque?a de colocar o campo (ID) como auto incremento, vou deixar o codigo da cria??o da tabela aqui, caso precisem.
USE [ColaboradorDB]
GO
/****** Object:?Table [dbo].[tb_tutorials]??Script Date: 05/02/2023 07:01:57 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tb_tutorials](
[id] [int] IDENTITY(1,1) NOT NULL,
[title] [nvarchar](100) NULL,
[description] [nvarchar](100) NULL,
[published] [nvarchar](100) NULL,
[status] [nvarchar](100) NULL
) ON [PRIMARY]
GO
Também é possível utilizar o modo Design para deixar o campo ID como auto incremento
Selecione o campo ID e nas op??es na grid abaixo do Sql Server selecione SIM e automaticamente é para aparecer nas duas op??es abaixo do campo identidade os valores 1,1. conforme a figura abaixo.
Feito isso, vamos criar a API em .net, vamos ao visual studio e crie uma aplica??o vazia, conforme a figura abaixo.
No próximo passo diga o nome do seu projeto.
No próximo passo algumas configura??es, desmarque ou n?o a op??o HTTPS, nesse exemplo n?o foi marcada.
No visual studio vamos montar a seguinte estrutura.
Antes de iniciar a cria??o das classes, instale os pacotes nuget utilizado no projeto, essas diretivas s?o importantes para o projeto funcionar corretamente.
Agora vamos criar as classes e pastas no gerenciador de solu??es do visual studio.
Vamos criar: 3 Pastas (Data, EndPoints, Extensions)
E 4 Classes: (Tutorials.cs, TutorialsContext.cs, TutorialsEndPoints.cs, ServiceColletionsExtensions.cs)
Conforme a figura abaixo.
Antes de iniciar com a cria??o das classes, vou deixar aqui o .json que é responsável pela a conex?o. appsettings.json
{
?"ConnectionString": "Data Source=DESKTOP-XXXXX\\SQLXXXXXXXEXPRESS;Initial Catalog=ColaboradorDB;Integrated Security=True",
?"Logging": {
??"LogLevel": {
???"Default": "Information",
???"Microsoft.AspNetCore": "Warning"
??}
?},
?"AllowedHosts": "*"
}
Essa string de conex?o é retirada da tela inicial do SQL Server conforme a figura abaixo.
launchSettings.json
{
?"iisSettings": {
??"windowsAuthentication": false,
??"anonymousAuthentication": true,
??"iisExpress": {
???"applicationUrl": "https://localhost:51569",
???"sslPort": 0
??}
?},
?"profiles": {
??"WebApiTutorials": {
???"commandName": "Project",
???"dotnetRunMessages": true,
???"launchBrowser": true,
???"launchUrl": "swagger",
???"applicationUrl": "https://localhost:5235",
???"environmentVariables": {
????"ASPNETCORE_ENVIRONMENT": "Development"
???}
??},
??"IIS Express": {
???"commandName": "IISExpress",
???"launchBrowser": true,
???"launchUrl": "swagger",
???"environmentVariables": {
????"ASPNETCORE_ENVIRONMENT": "Development"
???}
??}
?}
}
Agora vamos as classes
Tutorials.cs
using System.ComponentModel.DataAnnotations.Schema;
using System.Collections.Generic;
using System.Threading.Tasks;
[Table("Tb_tutorials")]
public record Tb_tutorials(int id, string title, string description, string published, string status);
//public List<Tb_tutorials> Tutorials { get; set; }
public interface ITutolialsRepository
{
??Task<List<Tb_tutorials>> GetTutorialsAsync();
??Task<Tb_tutorials> GetTutorialsByIdAsync(int id);
??Task<Tb_tutorials> GetTutorialsEContadorAsync();
??Task<int> SaveAsync(Tb_tutorials novoTutorial);
??Task<int> UpdateTutolialisStatusAsync(Tb_tutorials atualizaTutorial);
??Task<int> DeleteAsync(int id);
}
TutorialsContext.cs
using System.Data;
public class TutorialsContext
{
??public delegate Task<IDbConnection> GetConnection();
}
TutorialsEndPoints.cs
//using Microsoft.Extensions.Configuration;
using System;
using System.Threading.Tasks;
using Dapper; // Ativa o QueryFirstOrDefault
using System.Data.SqlClient;
using Dapper.Contrib.Extensions;
using static TutorialsContext;
//using System.Web.Http.Cors;
//using System.Text.Json;
//using Dapper; // Ativa o QueryFirstOrDefault
public static class TutorialsEndpoints
{
??public static void MapTutorialsEndpoints(this WebApplication app)
??{
????//app.EnableCors();
????app.MapGet("/", () => "Mini Tutorials API");
????app.MapGet("/tutorials", async (GetConnection connectionGetter) =>
????{
??????using var con = await connectionGetter();
??????//return con.GetAll<Tb_tutorials>().ToList();
??????string query = "SELECT * FROM dbo.Tb_tutorials";
??????List<Tb_tutorials> tutorials?= (await con.QueryAsync<Tb_tutorials>(sql:query)).ToList();
??????return tutorials;?
????});
????app.MapGet("/tutorials/{id}", async (GetConnection connectionGetter, int id) =>
????{
??????using var con = await connectionGetter();
??????//return con.Get<Tb_tutorials>(id);
??????return con.QueryFirstOrDefault<Tb_tutorials>("SELECT " + "id, " + "title, " + "description, " + "published, " + "status " + "FROM dbo.Tb_tutorials " + "WHERE id = @id ", new { id = id });
????});
????
????app.MapGet("/pesq-tutorials/title", async (GetConnection connectionGetter, string title) =>
????{
??????using var con = await connectionGetter();
??????return?con.QueryFirstOrDefault<Tb_tutorials>("SELECT " +"id, " +"title, " +"description, "+ "published, " + "status " +"FROM dbo.Tb_tutorials " + "WHERE title = @title ", new { title = title });
????});
????app.MapDelete("/del-tutorials/{id}", async (GetConnection connectionGetter, int id) =>
????{
??????using var con = await connectionGetter();
??????return con.QueryFirstOrDefault<Tb_tutorials>("DELETE " + "FROM dbo.Tb_tutorials " + "WHERE id = @id ", new { id = id });
????});
????app.MapPost("/novo-tutorials", async (GetConnection connectionGetter, Tb_tutorials Tutorials) =>
????{
??????using var con = await connectionGetter();
??????//var id = con.Insert(Tutorials);
??????//return Results.Created($"/tutorials/{id}", Tutorials);
??????string command = @"INSERT INTO dbo.Tb_tutorials(title, description, published, status)VALUES(@title, @description, @published, @status)";
??????var result = await con.ExecuteAsync(sql: command, param: Tutorials);
??????return result;
????});
????app.MapPut("/put-in-tutorials/{id}", async (GetConnection connectionGetter, int id, Tb_tutorials Tutorials) =>
????{
??????if (id > 0)
??????{
????????using var con = await connectionGetter();
????????string command = @"UPDATE dbo.Tb_tutorials SET title = @title, description = @description WHERE Id = @Id";
????????var result = await con.ExecuteAsync(sql: command, param: Tutorials);
????????return result;
??????}
??????else
??????{
????????using var con = await connectionGetter();
????????string command = @"INSERT INTO dbo.Tb_tutorials(title, description, published, status)VALUES(@title, @description, @published, @status)";
????????var result = await con.ExecuteAsync(sql: command, param: Tutorials);
????????return result;
??????}
????});
????app.MapPut("/tutorials", async (GetConnection connectionGetter, Tb_tutorials Tutorials) =>
????{
???????
????????using var con = await connectionGetter();
????????string command = @"UPDATE dbo.Tb_tutorials SET title = @title, description = @description WHERE Id = @Id";
????????var result = await con.ExecuteAsync(sql: command, param: Tutorials);
????????return result;
????});
????app.MapPut("/up-status-tutorials", async (GetConnection connectionGetter, Tb_tutorials Tutorials) =>
????{
??????using var con = await connectionGetter();
??????string command = @"UPDATE dbo.Tb_tutorials SET published = @published WHERE Id = @Id";
??????var result = await con.ExecuteAsync(sql: command, param: Tutorials);
??????return result;
????});
????app.MapPut("/put-tutorials", async (GetConnection connectionGetter, Tb_tutorials Tutorials) =>
????{
??????using var con = await connectionGetter();
??????string command = @"UPDATE dbo.Tb_tutorials SET title = @title, description = @description WHERE Id = @Id";
??????var result = await con.ExecuteAsync(sql: command, param: Tutorials);
??????return result;
??????});
??}
}
ServiceColletionsExtensions.cs
using System.Data.SqlClient;
using static TutorialsContext;
public static class ServiceCollectionsExtensions
{
??public static WebApplicationBuilder AddPersistence(this WebApplicationBuilder builder)
??{
????builder.Services.AddScoped<GetConnection>(sp =>
?????async () =>
?????{
???????string connectionString = sp.GetService<IConfiguration>()["ConnectionString"];
???????var connection = new SqlConnection(connectionString);
???????await connection.OpenAsync();
???????return connection;
?????});
????return builder;
??}
}
Por fim a classe program.cs
#region [Cors]
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
??options.AddPolicy(MyAllowSpecificOrigins,
?????????????policy =>
?????????????{
???????????????policy.WithOrigins("https://localhost:5235",
?????????????????????????"https://localhost:3000",
?????????????????????????"https://localhost:3000/tutorials",
?????????????????????????"https://localhost:3000/put-tutorials",
?????????????????????????"https://localhost:5235/put-tutorials",
?????????????????????????"https://localhost:3000/put-in-tutorials/",
?????????????????????????"https://localhost:5235/put-in-tutorials/",
?????????????????????????"https://localhost:3000/del-tutorials",
?????????????????????????"https://localhost:3000/novo-tutorials",
?????????????????????????"https://localhost:3000/pesq-tutorials/title")
?????????????????????????.AllowAnyHeader()
?????????????????????????//.AllowAnyMethod();
???????????????.WithMethods("POST","PUT", "DELETE", "GET", "PATCH", "OPTIONS")
???????????????.AllowCredentials();
?????????????});
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.AddPersistence();
var app = builder.Build();
app.UseCors(MyAllowSpecificOrigins);
app.MapTutorialsEndpoints();
app.UseSwagger();
app.UseSwaggerUI(c => { });
app.Run();
Execute a aplica??o.
Por fim, esse é o back-end.
Para o React Js, instale o node Js e o NMP. utilize esse link para mais detalhes https://docs.npmjs.com/downloading-and-installing-node-js-and-npm
Crie um projeto novo react seguindo esses passos.
Passo 1:
?- Criar uma pasta na área de trabalho (Desktop)
Passo 2:
?- Abrir a CMD do Windows como administrador
Passo 3:
?- Executar comandos:
???1 - cd C:\Users\XXXXXX\Desktop\React?
?????????- Substitua pelo o caminho do seu projeto.
???2 - npm install react@16
???3 - npx create-react-app nome-pasta-primeiro-projeto
???4 - Para abrir o projeto criado no navegador.
?????????- Continuando na CMD, digite o comando:
????????????1 - cd nome-pasta-primeiro-projeto
????????????2 - npm start.
No terminal dentro da pasta do projeto digite
npm install axios
npm add react-table
npm install react-router-dom
npm install react-bootstrap bootstrap
Instale também o visual code com esse link https://code.visualstudio.com/download
Execute a aplica??o no visual code conforme a figura abaixo. Abra um New Terminal e execute o comando nmp start.
Run
A estrutura segui conforme a figura abaixo.
Ent?o precisamos criar no projeto esses arquivos.
------------------------------------------------------------------
with-rounter.js
AddTutorial.js
Tutorial.js
TutorialsList.js
TutorialService.js
App.css
App.js
http-common.js
index.css
index.js
Pesquisa.js
serviceWorker.js
Table.css
Table.js
-----------------------------------------------------------------
with-rounter.js
import { useLocation, useNavigate, useParams } from "react-router-dom";
export const withRouter = (Component) => {
? function ComponentWithRouterProp(props) {
? ? let location = useLocation();
? ? let navigate = useNavigate();
? ? let params = useParams();
? ? return <Component {...props} router={{ location, navigate, params }} />;
? }
? return ComponentWithRouterProp;
};
AddTutorial.js
import React, { useState } from "react";
import TutorialDataService from "../services/TutorialService";
const AddTutorial = () => {
? const initialTutorialState = {
? ? id: null,
? ? title: "",
? ? description: "",
? ? published: false
? };
? const [tutorial, setTutorial] = useState(initialTutorialState);
? const [submitted, setSubmitted] = useState(false);
? const handleInputChange = event => {
? ? const { name, value } = event.target;
? ? setTutorial({ ...tutorial, [name]: value });
? };
? const saveTutorial = () => {
? ? var data = {
? ? ? title: tutorial.title,
? ? ? description: tutorial.description
? ? ? //published: "Publicado"
? ? };
? ? TutorialDataService.create(data)
? ? ? .then(response => {
? ? ? ? setTutorial({
? ? ? ? ? id: response.data.id,
? ? ? ? ? title: response.data.title,
? ? ? ? ? description: response.data.description,
? ? ? ? ? published: response.data.published
? ? ? ? });
? ? ? ? if (tutorial.id){
? ? ? ? ? ?tutorial.published=true;
? ? ? ? ? ?console.log("Se tiver id:"+tutorial.id+": a variavél public recebe:"+tutorial.published);
? ? ? ? }
? ? ? ? setSubmitted(true);
? ? ? ? console.log(response.data);
? ? ? })
? ? ? .catch(e => {
? ? ? ? console.log(e);
? ? ? });
? };
? const newTutorial = () => {
? ? setTutorial(initialTutorialState);
? ? setSubmitted(false);
? };
? return (
? ? <div className="submit-form">
? ? ? {submitted ? (
? ? ? ? <div>
? ? ? ? ? <h4>Cadastro realizado com sucesso!</h4>
? ? ? ? ? <button className="btn btn-success" onClick={newTutorial}>
? ? ? ? ? ? Adicionar
? ? ? ? ? </button>
? ? ? ? </div>
? ? ? ) : (
? ? ? ? <div>
? ? ? ? ? <div className="form-group">
? ? ? ? ? ? <label htmlFor="title">Titulo</label>
? ? ? ? ? ? <input
? ? ? ? ? ? ? type="text"
? ? ? ? ? ? ? className="form-control"
? ? ? ? ? ? ? id="title"
? ? ? ? ? ? ? required
? ? ? ? ? ? ? value={tutorial.title}
? ? ? ? ? ? ? onChange={handleInputChange}
? ? ? ? ? ? ? name="title"
? ? ? ? ? ? />
? ? ? ? ? </div>
? ? ? ? ? <div className="form-group">
? ? ? ? ? ? <label htmlFor="description">Descri??o</label>
? ? ? ? ? ? <input
? ? ? ? ? ? ? type="text"
? ? ? ? ? ? ? className="form-control"
? ? ? ? ? ? ? id="description"
? ? ? ? ? ? ? required
? ? ? ? ? ? ? value={tutorial.description}
? ? ? ? ? ? ? onChange={handleInputChange}
? ? ? ? ? ? ? name="description"
? ? ? ? ? ? />
? ? ? ? ? </div>
? ? ? ? ? <button onClick={saveTutorial} className="btn btn-success">
? ? ? ? ? ? Salvar
? ? ? ? ? </button>
? ? ? ? </div>
? ? ? )}
? ? </div>
? );
};
export default AddTutorial;
Tutorial.js
import React, { Component } from "react";
//import TutorialDataService from "../services/tutorial.service";
import TutorialDataService from "../services/TutorialService";
import { withRouter } from '../common/with-router';
//import axios from "axios";
//import React from "react";
class Tutorial extends Component {
? constructor(props) {
? ? super(props);
? ? this.onChangeTitle = this.onChangeTitle.bind(this);
? ? this.onChangeDescription = this.onChangeDescription.bind(this);
? ? this.getTutorial = this.getTutorial.bind(this);
? ? this.updatePublished = this.updatePublished.bind(this);
? ? this.updateTutorial = this.updateTutorial.bind(this);
? ? this.deleteTutorial = this.deleteTutorial.bind(this);
? ? this.state = {
? ? ? currentTutorial: {
? ? ? ? id: null,
? ? ? ? title: "",
? ? ? ? description: "",
? ? ? ? published: "",
? ? ? ? status:""
? ? ? },
? ? ? message: ""
? ? };
? }
? componentDidMount() {
? ? this.getTutorial(this.props.router.params.id);
? }
? onChangeTitle(e) {
? ? const title = e.target.value;
? ? this.setState(function(prevState) {
? ? ? return {
? ? ? ? currentTutorial: {
? ? ? ? ? ...prevState.currentTutorial,
? ? ? ? ? title: title
? ? ? ? }
? ? ? };
? ? });
? }
? onChangeDescription(e) {
? ? const description = e.target.value;
? ?
? ? this.setState(prevState => ({
? ? ? currentTutorial: {
? ? ? ? ...prevState.currentTutorial,
? ? ? ? description: description
? ? ? }
? ? }));
? }
? getTutorial(id) {
? ? TutorialDataService.get(id)
? ? ? .then(response => {
? ? ? ? this.setState({
? ? ? ? ? currentTutorial: response.data
? ? ? ? });
? ? ? ? console.log(response.data);
? ? ? })
? ? ? .catch(e => {
? ? ? ? console.log(e);
? ? ? });
? }
? updatePublished(status) {
? ? var data = {
? ? ? id: this.state.currentTutorial.id,
? ? ? //title: this.state.currentTutorial.title,
? ? ? //description: this.state.currentTutorial.description,
? ? ? published: status.toString()
? ? };
? ?/* var dados = {
? ? ? ? 'id': this.state.currentTutorial.id,
? ? ? ? 'title': this.state.currentTutorial.title,
? ? ? ? 'description': this.state.currentTutorial.description,
? ? ? ? 'published': this.state.currentTutorial.published.toString()
? ? ? };*/
? ? TutorialDataService.updateStatus(this.state.currentTutorial.id, data)
? ? ? .then(response => {
? ? ? ? this.setState(prevState => ({
? ? ? ? ? currentTutorial: {
? ? ? ? ? ? ...prevState.currentTutorial,
? ? ? ? ? ? published: status
? ? ? ? ? }
? ? ? ? }));
? ? ? ? console.log(response.data);
? ? ? })
? ? ? .catch(e => {
? ? ? ? console.log(e);
? ? ? });
? }
? updateTutorial() {
? ? // console.log(this.state.currentTutorial.id);
? ? // console.log(this.state.currentTutorial);
? ? var data = {
? ? ? ? ? ? 'id': this.state.currentTutorial.id,
? ? ? ? ? ? 'title': this.state.currentTutorial.title,
? ? ? ? ? ? 'description': this.state.currentTutorial.description//,
? ? ? ? ? ? //'published': this.state.currentTutorial.published.toString()
? ? ? ? ? ? //published:"published",
? ? ? ? ? ? //status:"status"
? ? ? ? ? };
?
? ? const json = JSON.stringify(data);
? ? console.log("DATA<>::"+json);
? ? //console.log(typeof json);
? ? this.state.currentTutorial = data;
? ? console.log("CURRENT_TUTORIAL:::"+this.state.currentTutorial);
? ? TutorialDataService.update(
? ? ? this.state.currentTutorial.id,
? ? ? this.state.currentTutorial
? ? )
? ? ? .then(response => {
? ? ? ? console.log(response.data);
? ? ? ? this.setState({
? ? ? ? ? message: "Dados alterados com sucesso!"
? ? ? ? });
? ? ? })
? ? ? .catch(e => {
? ? ? ? console.log(e);
? ? ?
? ? ? });
? }
? deleteTutorial() { ? ?
? ? TutorialDataService.delete(this.state.currentTutorial.id)
? ? ? .then(response => {
? ? ? ? console.log(response.data);
? ? ? ? this.props.router.navigate('/tutorials');
? ? ? })
? ? ? .catch(e => {
? ? ? ? console.log(e);
? ? ? });
? }
? render() {
? ? const { currentTutorial } = this.state;
? ? return (
? ? ? <div>
? ? ? ? {currentTutorial ? (
? ? ? ? ? <div className="edit-form">
? ? ? ? ? ? <h4>Tutorial</h4>
? ? ? ? ? ? <form>
? ? ? ? ? ? ? <div className="form-group">
? ? ? ? ? ? ? ? <label htmlFor="title">Titulo</label>
? ? ? ? ? ? ? ? <input
? ? ? ? ? ? ? ? ? type="text"
? ? ? ? ? ? ? ? ? className="form-control"
? ? ? ? ? ? ? ? ? id="title"
? ? ? ? ? ? ? ? ? value={currentTutorial.title}
? ? ? ? ? ? ? ? ? onChange={this.onChangeTitle}
? ? ? ? ? ? ? ? />
? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? <div className="form-group">
? ? ? ? ? ? ? ? <label htmlFor="description">Descri??o</label>
? ? ? ? ? ? ? ? <input
? ? ? ? ? ? ? ? ? type="text"
? ? ? ? ? ? ? ? ? className="form-control"
? ? ? ? ? ? ? ? ? id="description"
? ? ? ? ? ? ? ? ? value={currentTutorial.description}
? ? ? ? ? ? ? ? ? onChange={this.onChangeDescription}
? ? ? ? ? ? ? ? />
? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? <div className="form-group">
? ? ? ? ? ? ? ? <label>
? ? ? ? ? ? ? ? ? <strong>Status:</strong>
? ? ? ? ? ? ? ? </label>
? ? ? ? ? ? ? ? {currentTutorial.published ? "Publicado" : "Pendente"}
? ? ? ? ? ? ? </div>
? ? ? ? ? ? </form>
? ? ? ? ? ? {currentTutorial.published ? (
? ? ? ? ? ? ? <></>
? ? ? ? ? ? ? /*<button
? ? ? ? ? ? ? ? className="btn btn-primary"
? ? ? ? ? ? ? ? onClick={() => this.updatePublished(false)}
? ? ? ? ? ? ? ? //onClick={() => ""}
? ? ? ? ? ? ? >
? ? ? ? ? ? ? ? DesPublicar
? ? ? ? ? ? ? </button>*/
? ? ? ? ? ? ) : (
? ? ? ? ? ? ? <></>
? ? ? ? ? ? ? /*<button
? ? ? ? ? ? ? ? className="btn btn-primary"
? ? ? ? ? ? ? ? onClick={() => this.updatePublished(true)}
? ? ? ? ? ? ? ? //onClick={() => ""}
? ? ? ? ? ? ? >
? ? ? ? ? ? ? ? Publicar
? ? ? ? ? ? ? </button>*/
? ? ? ? ? ? )}
? ? ? ? ? ? <button
? ? ? ? ? ? ? className="btn btn-danger"
? ? ? ? ? ? ? onClick={this.deleteTutorial}
? ? ? ? ? ? >
? ? ? ? ? ? ? Excluir
? ? ? ? ? ? </button>
? ? ? ? ? ? <button
? ? ? ? ? ? ? type="submit"
? ? ? ? ? ? ? className="btn btn-success"
? ? ? ? ? ? ? onClick={this.updateTutorial}
? ? ? ? ? ? >
? ? ? ? ? ? ? Alterar
? ? ? ? ? ? </button>
? ? ? ? ? ? <p>{this.state.message}</p>
? ? ? ? ? </div>
? ? ? ? ) : (
? ? ? ? ? <div>
? ? ? ? ? ? <br />
? ? ? ? ? ? <p>Por favor clique no item da lista...</p>
? ? ? ? ? </div>
? ? ? ? )}
? ? ? </div>
? ? );
? }
}
export default withRouter(Tutorial);
TutorialsList.js
import React, { useState, useEffect} from "react";
import TutorialDataService from "../services/TutorialService";
import { Link } from "react-router-dom";
//import Table from 'react-bootstrap/Table';
const TutorialsList = () => {
? const [tutorials, setTutorials] = useState([]);
? const [currentTutorial, setCurrentTutorial] = useState(null);
? const [currentIndex, setCurrentIndex] = useState(-1);
? const [searchTitle, setSearchTitle] = useState("");
?/* this.state = {
? ? message: ""
? };*/
? useEffect(() => {
? ? retrieveTutorials();
? }, []);
? const onChangeSearchTitle = e => {
? ? const searchTitle = e.target.value;
? ? setSearchTitle(searchTitle);
? };
? const retrieveTutorials = () => {
? ? TutorialDataService.getAll()
? ? ? .then(response => {
? ? ? ? setTutorials(response.data);
? ? ? ? console.log(response.data);
? ? ? })
? ? ? .catch(e => {
? ? ? ? console.log(e);
? ? ? });
? };
? const refreshList = () => {
? ? retrieveTutorials();
? ? setCurrentTutorial(null);
? ? setCurrentIndex(-1);
? };
? const setActiveTutorial = (tutorial, index) => {
? ? setCurrentTutorial(tutorial);
? ? setCurrentIndex(index);
? };
? const removeAllTutorials = () => {
? ? TutorialDataService.removeAll()
? ? ? .then(response => {
? ? ? ? console.log(response.data);
? ? ? ? refreshList();
? ? ? })
? ? ? .catch(e => {
? ? ? ? console.log(e);
? ? ? });
? };
? const findByTitle = () => {
? ? TutorialDataService.findByTitle(searchTitle)
? ? ? .then(response => {
? ? ? ?
? ? ? ? //setTutorials(response.data);
? ? ? ? //this.props.router.navigate('/tutorials/'+currentTutorial.id);
领英推荐
? ? ? ?/* this.setState({
? ? ? ? ? message: "Dados encontrados, "+this.state.currentTutorial.title
? ? ? ? });*/
? ? ? ? console.log(response.data);
? ? ? ? const json = JSON.stringify(response.data);
? ? ? ? console.log('Dados encontrato com sucesso! '+json);
? ? ? ? //console.log('Pesquisa encontrada, '+json.data("title"));
? ? ? ?/* this.setState({
? ? ? ? ? message: json
? ? ? ? });*/
? ? ? ? //setTutorials(json);
? ? ? })
? ? ? .catch(e => {
? ? ? ? console.log(e);
? ? ? });
? };
? return (
?
? ? <div className="list row">
? ? ? <div className="col-md-8">
? ? ? ? <div className="input-group mb-3">
? ? ? ? ? <input
? ? ? ? ? ? id="txt_consulta"
? ? ? ? ? ? type="text"
? ? ? ? ? ? className="form-control"
? ? ? ? ? ? placeholder="Informe o titulo que deseja pesquisar"
? ? ? ? ? ? value={searchTitle}
? ? ? ? ? ? onChange={onChangeSearchTitle}
? ? ? ? ? />
? ? ? ? ? <div className="input-group-append">
? ? ? ? ? ? <button
? ? ? ? ? ? ? className="btn btn-outline-secondary"
? ? ? ? ? ? ? type="button"
? ? ? ? ? ? ? onClick={findByTitle}
? ? ? ? ? ? >
? ? ? ? ? ? ? Pesquisar
? ? ? ? ? ? </button>
? ? ? ? ? </div>
? ? ? ? </div>
? ? ? </div>
? ? ? <div className="col-md-6">
? ? ? ? <h4>Lista de Tutorial</h4>
? ? ? ? <table id="tabela" class="table table-hover">
? ? ? ? <tbody><tr><th>
? ? ?
? ? ? ? <ul className="list-group">
? ? ? ? ? {tutorials &&
? ? ? ? ? ? tutorials.map((tutorial, index) => (
? ? ? ? ? ? ? <li
? ? ? ? ? ? ? ? className={
? ? ? ? ? ? ? ? ? "list-group-item " + (index === currentIndex ? "active" : "")
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? onClick={() => setActiveTutorial(tutorial, index)}
? ? ? ? ? ? ? ? key={index}
? ? ? ? ? ? ? >
? ? ? ? ? ? ? ? {tutorial.title}
? ? ? ? ? ? ? </li>
? ? ? ? ? ? ))}
? ? ? ? </ul>
? ? ? ? </th></tr></tbody></table>
? ? ? ? <button
? ? ? ? ? className="m-3 btn btn-sm btn-danger"
? ? ? ? ? onClick={removeAllTutorials}
? ? ? ? >
? ? ? ? ? Excluir todos
? ? ? ? </button>
? ? ? </div>
? ? ? <div className="col-md-6">
? ? ? ? {currentTutorial ? (
? ? ? ? ? <div>
? ? ? ? ? ? <h4>Tutorial</h4>
? ? ? ? ? ? <div>
? ? ? ? ? ? ? <label>
? ? ? ? ? ? ? ? <strong>Titulo:</strong>
? ? ? ? ? ? ? </label>{" "}
? ? ? ? ? ? ? {currentTutorial.title}
? ? ? ? ? ? </div>
? ? ? ? ? ? <div>
? ? ? ? ? ? ? <label>
? ? ? ? ? ? ? ? <strong>Descri??o:</strong>
? ? ? ? ? ? ? </label>{" "}
? ? ? ? ? ? ? {currentTutorial.description}
? ? ? ? ? ? </div>
? ? ? ? ? ? <div>
? ? ? ? ? ? ? <label>
? ? ? ? ? ? ? ? <strong>Status:</strong>
? ? ? ? ? ? ? </label>{" "}
? ? ? ? ? ? ? {currentTutorial.published ? "Publicado" : "Pendente"}
? ? ? ? ? ? </div>
? ? ? ? ? ? <Link
? ? ? ? ? ? ? to={"/tutorials/" + currentTutorial.id}
? ? ? ? ? ? ? className="btn btn-warning"
? ? ? ? ? ? >
? ? ? ? ? ? ?{currentTutorial.id}
? ? ? ? ? ? ? Editar
? ? ? ? ? ? </Link>
? ? ? ? ? </div>
? ? ? ? ) : (
? ? ? ? ? <div>
? ? ? ? ? ? <br />
? ? ? ? ? ? <p>Por favor clique em uma op??o da lista...</p>
? ? ? ? ? </div>
? ? ? ? )}
? ? ? </div>
? ? </div>
? );
};
export default TutorialsList;
TutorialService.js
import http from "../http-common";
class TutorialDataService {
? getAll() {
? ? return http.get("/tutorials");
? }
? get(id) {
? ? return http.get(`/tutorials/${id}`);
? }
? create(data) {
? ? return http.post("/novo-tutorials", data);
? }
? update(id, data) {
? ? console.log(http.put(id));
? ? return http.put(`/put-tutorials`,data);
? }
? updateStatus(id, data) {
? ? console.log(http.put(id));
? ? return http.put(`/up-status-tutorials`,data);
? }
? delete(id) {
? ? return http.delete(`/del-tutorials/${id}`);
? }
? deleteAll() {
? ? return http.delete(`/del-tutorials`);
? }
? findByTitle(title) {
? ? return http.get(`/pesq-tutorials/title?title=${title}`);
? }
}
export default new TutorialDataService();
App.css
.list {
? ? text-align: left;
? ? max-width: 750px;
? ? margin: auto;
? }
?
? .submit-form {
? ? max-width: 300px;
? ? margin: auto;
? }
?
? .edit-form {
? ? max-width: 300px;
? ? margin: auto;
? }
? .btn {
? ? border: none;
? ? padding: 10px;
? ? text-decoration: none;
? ? cursor: pointer;
? ? transition: background .3s;
? ? border-radius: 5px;
}
/*SUCCESS*/
.btn-sucesso {
? ? background-color: var(#006400);
? ? outline: none;
? ? color: var(#FFFAF0)
}
.btn-excluir {
? background-color: var(#FF0000);
? outline: none;
? color: var(#FFFAF0)
}
App.js
import React from "react";
import { Routes, Route, Link } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css";
import AddTutorial from "./components/AddTutorial";
import Tutorial from "./components/Tutorial";
import TutorialsList from "./components/TutorialsList";
import Pesquisa from "./Pesquisa";
function App() {
? return (
? ? <div>
? ? ? <nav className="navbar navbar-expand navbar-dark bg-dark">
? ? ? ? <a href="/tutorials" className="navbar-brand">
? ? ? ? ? Inicio
? ? ? ? </a>
? ? ? ? <div className="navbar-nav mr-auto">
? ? ? ? ? <li className="nav-item">
? ? ? ? ? ? <Link to={"/tutorials"} className="nav-link">
? ? ? ? ? ? ? Tutorial
? ? ? ? ? ? </Link>
? ? ? ? ? </li>
? ? ? ? ? <li className="nav-item">
? ? ? ? ? ? <Link to={"/add"} className="nav-link">
? ? ? ? ? ? ? Cadastro
? ? ? ? ? ? </Link>
? ? ? ? ? </li>
? ? ? ? ? <li className="nav-item">
? ? ? ? ? ? <Link to={"/Pesquisa"} className="nav-link">
? ? ? ? ? ? ? Pesquisa
? ? ? ? ? ? </Link>
? ? ? ? ? </li>
? ? ? ? ?
? ? ? ? ?
? ? ? ? </div>
? ? ? </nav>
? ? ? <div className="container mt-3">
? ? ? ? <Routes>
? ? ? ? ? <Route path="/" element={<TutorialsList/>} />
? ? ? ? ? <Route path="/tutorials" element={<TutorialsList/>} />
? ? ? ? ? <Route path="/add" element={<AddTutorial/>} />
? ? ? ? ? <Route path="/tutorials/:id" element={<Tutorial/>} />
? ? ? ? ? <Route path="/pesquisa" element={<Pesquisa/>} />
? ? ?
? ? ? ? </Routes>
? ? ? </div>
? ? </div>
? ); ?
}
export default App;
http-common.js
import axios from "axios";
export default axios.create({
? //baseURL: "https://localhost:8080/api",
? baseURL: "https://localhost:5235",
? headers: {
? ? "Content-type": "application/json",
? ? "Access-Control-Allow-Origin": "*",
? ? "Access-Control-Allow-Methods": "GET,PUT,POST,DELETE,PATCH,OPTIONS",
? ? "Access-Control-Allow-Headers":"*",
? ? "X-Requested-with":"*",
? ? "Content_Type":"*",
? ? "Accept":"*",
? ? "Authorization":"https://localhost:5235"
? }
});
index.css
body {
? margin: 0;
? font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
? ? 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
? ? sans-serif;
? -webkit-font-smoothing: antialiased;
? -moz-osx-font-smoothing: grayscale;
}
code {
? font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
? ? monospace;
}
index.js
import React from "react";
//import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import ReactDOM from 'react-dom/client';
import App from "./App";
import * as serviceWorker from "./serviceWorker";
/*ReactDOM.render(
? <BrowserRouter>
? ? <App />
? </BrowserRouter>,
? document.getElementById("root")
);*/
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
? <BrowserRouter>
? ? <App />
? </BrowserRouter>
);
serviceWorker.unregister();
Pesquisa.js
import './App.css';
import { useEffect, useMemo, useState } from 'react';
import axios from "axios"
import Table from './Table';
function Pesquisa() {
//--Para testar o table customizado
? // Array com os passageiros falsos da API
? const [data, setData] = useState([])
? // Número total de páginas
? const [totalPages, setTotalPages] = useState(1)
? // Número total de passageiros
? const [totalPassengers, setTotalPassengers] = useState(1)
? // Hook para fazer a primeira chamada do componente
? useEffect(() => {
? ? // Fun??o para recuperar informa??es da API
? ? axios.get("https://localhost:5235/tutorials")
? ? ? .then((res) => {
? ? ? ? const json = JSON.stringify(res);
? ? ? ? const obj = JSON.parse(json);
? ? ? ? console.log("json: "+json);
? ? ? ? console.log("obj: "+obj);
? ? ? ? console.log("res: "+res);
? ? ? ? console.log("res_data: "+res.data);
? ? ? ?const {data} = obj
? ? ? ?setData(data)
? ? ? ?
? ? ? })
? }, [])
? // Colunas da nossa tabela
? const columns = useMemo(
? ? () => [
? ? ? {
? ? ? ? //Tabela de teste inicio
? ? ? ? // Primeiro grupo - Informa??es do passageiro
? ? ? ? Header: "Informa??es dos tutoriais",
? ? ? ? // Colunas do primeiro grupo
? ? ? ? columns: [
? ? ? ? ? {
? ? ? ? ? ? Header: "Nome",
? ? ? ? ? ? accessor: "title"
? ? ? ? ? },
? ? ? ? ? {
? ? ? ? ? ? Header: "Descri??o",
? ? ? ? ? ? accessor: "description"
? ? ? ? ? }
? ? ? ? ]
? ? ? }
? ? ],
? ? []
? );
? return (
? ? ? <div className="App">
? ? ? ? <Table columns={columns} data={data} />
? ? ? </div>
? );
}
export default Pesquisa;
?
serviceWorker.js
const isLocalhost = Boolean(
? ? window.location.hostname === 'localhost' ||
? ? ? // [::1] is the IPv6 localhost address.
? ? ? window.location.hostname === '[::1]' ||
? ? ? // 127.0.0.0/8 are considered localhost for IPv4.
? ? ? window.location.hostname.match(
? ? ? ? /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
? ? ? )
? );
?
? export function register(config) {
? ? if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
? ? ? // The URL constructor is available in all browsers that support SW.
? ? ? const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
? ? ? if (publicUrl.origin !== window.location.origin) {
? ? ? ? // Our service worker won't work if PUBLIC_URL is on a different origin
? ? ? ? // from what our page is served on. This might happen if a CDN is used to
? ? ? ? // serve assets; see https://github.com/facebook/create-react-app/issues/2374
? ? ? ? return;
? ? ? }
?
? ? ? window.addEventListener('load', () => {
? ? ? ? const swUrl = '${process.env.PUBLIC_URL}/service-worker.js';
?
? ? ? ? if (isLocalhost) {
? ? ? ? ? // This is running on localhost. Let's check if a service worker still exists or not.
? ? ? ? ? checkValidServiceWorker(swUrl, config);
?
? ? ? ? ? // Add some additional logging to localhost, pointing developers to the
? ? ? ? ? // service worker/PWA documentation.
? ? ? ? ? navigator.serviceWorker.ready.then(() => {
? ? ? ? ? ? console.log(
? ? ? ? ? ? ? 'This web app is being served cache-first by a service ' +
? ? ? ? ? ? ? ? 'worker. To learn more, visit https://bit.ly/CRA-PWA'
? ? ? ? ? ? );
? ? ? ? ? });
? ? ? ? } else {
? ? ? ? ? // Is not localhost. Just register service worker
? ? ? ? ? registerValidSW(swUrl, config);
? ? ? ? }
? ? ? });
? ? }
? }
?
? function registerValidSW(swUrl, config) {
? ? navigator.serviceWorker
? ? ? .register(swUrl)
? ? ? .then(registration => {
? ? ? ? registration.onupdatefound = () => {
? ? ? ? ? const installingWorker = registration.installing;
? ? ? ? ? if (installingWorker == null) {
? ? ? ? ? ? return;
? ? ? ? ? }
? ? ? ? ? installingWorker.onstatechange = () => {
? ? ? ? ? ? if (installingWorker.state === 'installed') {
? ? ? ? ? ? ? if (navigator.serviceWorker.controller) {
? ? ? ? ? ? ? ? // At this point, the updated precached content has been fetched,
? ? ? ? ? ? ? ? // but the previous service worker will still serve the older
? ? ? ? ? ? ? ? // content until all client tabs are closed.
? ? ? ? ? ? ? ? console.log(
? ? ? ? ? ? ? ? ? 'New content is available and will be used when all ' +
? ? ? ? ? ? ? ? ? ? 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
? ? ? ? ? ? ? ? );
?
? ? ? ? ? ? ? ? // Execute callback
? ? ? ? ? ? ? ? if (config && config.onUpdate) {
? ? ? ? ? ? ? ? ? config.onUpdate(registration);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? // At this point, everything has been precached.
? ? ? ? ? ? ? ? // It's the perfect time to display a
? ? ? ? ? ? ? ? // "Content is cached for offline use." message.
? ? ? ? ? ? ? ? console.log('Content is cached for offline use.');
?
? ? ? ? ? ? ? ? // Execute callback
? ? ? ? ? ? ? ? if (config && config.onSuccess) {
? ? ? ? ? ? ? ? ? config.onSuccess(registration);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? };
? ? ? ? };
? ? ? })
? ? ? .catch(error => {
? ? ? ? console.error('Error during service worker registration:', error);
? ? ? });
? }
?
? function checkValidServiceWorker(swUrl, config) {
? ? // Check if the service worker can be found. If it can't reload the page.
? ? fetch(swUrl, {
? ? ? headers: { 'Service-Worker': 'script' }
? ? })
? ? ? .then(response => {
? ? ? ? // Ensure service worker exists, and that we really are getting a JS file.
? ? ? ? const contentType = response.headers.get('content-type');
? ? ? ? if (
? ? ? ? ? response.status === 404 ||
? ? ? ? ? (contentType != null && contentType.indexOf('javascript') === -1)
? ? ? ? ) {
? ? ? ? ? // No service worker found. Probably a different app. Reload the page.
? ? ? ? ? navigator.serviceWorker.ready.then(registration => {
? ? ? ? ? ? registration.unregister().then(() => {
? ? ? ? ? ? ? window.location.reload();
? ? ? ? ? ? });
? ? ? ? ? });
? ? ? ? } else {
? ? ? ? ? // Service worker found. Proceed as normal.
? ? ? ? ? registerValidSW(swUrl, config);
? ? ? ? }
? ? ? })
? ? ? .catch(() => {
? ? ? ? console.log(
? ? ? ? ? 'No internet connection found. App is running in offline mode.'
? ? ? ? );
? ? ? });
? }
?
? export function unregister() {
? ? if ('serviceWorker' in navigator) {
? ? ? navigator.serviceWorker.ready
? ? ? ? .then(registration => {
? ? ? ? ? registration.unregister();
? ? ? ? })
? ? ? ? .catch(error => {
? ? ? ? ? console.error(error.message);
? ? ? ? });
? ? }
? }
Table.css
table {
? ? font-family: Arial, Helvetica, sans-serif;
? ? border-collapse: collapse;
? ? width: 100%;
? }
? table td, table th {
? ? border: 1px solid #ddd;
? ? padding: 8px;
? }
? table tr:nth-child(even){background-color: #f2f2f2;}
? table tr:hover {background-color: #ddd;}
? table th {
? ? padding-top: 12px;
? ? padding-bottom: 12px;
? ? text-align: left;
? ? background-color: #04AA6D;
? ? color: white;
? }
Table.js
//instalar ?yarn add react-table ou npm add react-table
//import React from "react";
import { useTable, useFilters} from "react-table";
import React, { useState} from "react";
import "./Table.css";
function Table({ columns, data }) {
?
? // Utilizando o hook useTable e passando as colunas com os dados.
? // é retornado para a gente todas as informa??es necessárias para
? // montar a tabela.
? const {
? ? getTableProps, // propriedades da tabela
? ? getTableBodyProps, // propriedades do corpo da tabela
? ? headerGroups, // os valores de agrupamento de tabela, caso sua tabela use
? ? rows, // linhas da tabela baseado nos dados e colunas
? ? prepareRow, // Prepara a linha (Essa fun??o deve ser chamada para cada linha)
? ? setFilter // Com a passagem do hook useFilters, temos a possibilidade filtrar a tabela com a fun??o setFilter
? } = useTable({
? ? columns,
? ? data
? },
? ?useFilters//, // adicionando o hook useFilters na tabela
? ?//useSortBy // Este hook nos ajuda a reorganizar a tabela
);
? ? ?
? ? ? // Criando o estado
? ? ? const [valueInput, setValueInput] = useState("");
? ? ? // Atualiza o estado quando o valor muda
? ? ? const handleValueChange = e => {
? ? ? ? const value = e.target.value || undefined;
? ? ? ? setFilter("title", value); // Atualiza o nome filtro "name". Com isso, a tabela sabe fazer a busca e mostrar apenas elementos parecidos com esse
? ? ? ? setValueInput(value);
? ? ? };
? ?// Input element
? ?/*<input
? ? ? value={valueInput}
? ? ? onChange={handleValueChange}
? ? ? placeholder={"Busca pelo nome"}
? ? ? />*/
? /*
? ? Aqui renderizamos a nossa tabela.
? ? Como já sabemos, o React Table n?o possui nenhum comportamento visual, logo,
? ? depende que a gente adicione os elementos e estilo.
? ? O React Table vai ajudar a gente a controlar os estados e lógicas da tabela.
? */
? return (
? ? <table {...getTableProps()}>
? ? ? <thead>
? ? ? ? {headerGroups.map(headerGroup => (
? ? ? ? ? ?
? ? ? ? ? <tr {...headerGroup.getHeaderGroupProps()}>
? ? ? ? ? ? {headerGroup.headers.map(column => (
? ? ? ? ? ? ? <th {...column.getHeaderProps()}>{column.render("Header")}</th>
? ? ? ? ? ? ))}
? ? ? ? ? </tr>
? ? ? ? ))}
? ? ? </thead>
? ? ? <input
value={valueInput}
onChange={handleValueChange}
placeholder={"Busca pelo nome"}
/>
? ? ? <tbody {...getTableBodyProps()}>
? ? ? ? {rows.map((row, i) => {
? ? ? ? ? prepareRow(row);
? ? ? ? ? return (
? ? ? ? ? ? <tr {...row.getRowProps()}>
? ? ? ? ? ? ? {row.cells.map(cell => {
? ? ? ? ? ? ? ? return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
? ? ? ? ? ? ? })}
? ? ? ? ? ? </tr>
? ? ? ? ? );
? ? ? ? })}
? ? ? </tbody>
? ? </table>
? );
}
export default Table;
------------------------------------------------------------------------------------
Execute a aplica??o.
Abaixo as figuras da aplica??o funcionando.
Vamos adicionar dois bot?es na pesquisa, um para gerar o .csv e outro para chamar o print para gerar um .pdf ou enviar para a impressora padr?o.
Vamos mudar o nosso Table.js mais antes execute no terminal esses dois comandos.
npm add antd
npm add react-csv
npm add react-to-print
Table.js
import { useTable, useFilters} from "react-table";
import React, { useState, useRef} from "react";
import "./Table.css";
import {CSVLink} from "react-csv"
//import { Table} from "antd";
import { useReactToPrint } from 'react-to-print';
import { FilePdfOutlined } from '@ant-design/icons';
import { Button} from "antd";
function Table({ columns, data }) {
? const componentRef = useRef();
? const handlePrint = useReactToPrint({
? ? content: () => componentRef.current,
? });
? // Utilizando o hook useTable e passando as colunas com os dados.
? // é retornado para a gente todas as informa??es necessárias para
? // montar a tabela.
? const {
? ? getTableProps, // propriedades da tabela
? ? getTableBodyProps, // propriedades do corpo da tabela
? ? headerGroups, // os valores de agrupamento de tabela, caso sua tabela use
? ? rows, // linhas da tabela baseado nos dados e colunas
? ? prepareRow, // Prepara a linha (Essa fun??o deve ser chamada para cada linha)
? ? setFilter // Com a passagem do hook useFilters, temos a possibilidade filtrar a tabela com a fun??o setFilter
? } = useTable({
? ? columns,
? ? data
? },
? ?useFilters//, // adicionando o hook useFilters na tabela
? ?//useSortBy // Este hook nos ajuda a reorganizar a tabela
);
? ? ?
? ? ? // Criando o estado
? ? ? const [valueInput, setValueInput] = useState("");
? ? ? // Atualiza o estado quando o valor muda
? ? ? const handleValueChange = e => {
? ? ? ? const value = e.target.value || undefined;
? ? ? ? setFilter("title", value); // Atualiza o nome filtro "name". Com isso, a tabela sabe fazer a busca e mostrar apenas elementos parecidos com esse
? ? ? ? setValueInput(value);
? ? ? };
? ?// Input element
? ?/*<input
? ? ? value={valueInput}
? ? ? onChange={handleValueChange}
? ? ? placeholder={"Busca pelo nome"}
? ? ? />*/
? /*
? ? Aqui renderizamos a nossa tabela.
? ? Como já sabemos, o React Table n?o possui nenhum comportamento visual, logo,
? ? depende que a gente adicione os elementos e estilo.
? ? O React Table vai ajudar a gente a controlar os estados e lógicas da tabela.
? */
? ? /*
? ? <CSVLink
? ? ? ? ? ? ? filename={"Expense_Table.csv"}
? ? ? ? ? ? ? data={myList}
? ? ? ? ? ? ? className="btn btn-primary"
? ? ? ? ? ? >
? ? ? ? ? ? ? Export to CSV
? ? ? ? ? ? </CSVLink>
? ? ? ? ? ? <Button onClick={handlePrint} type="primary" danger> Export to PDF </Button>
? ? */
? return (
? ? <div ref={componentRef}>
? ? <table {...getTableProps()}>
? ? ? <thead>
? ? ? ? {headerGroups.map(headerGroup => (
? ? ? ? ? ?
? ? ? ? ? <tr {...headerGroup.getHeaderGroupProps()}>
? ? ? ? ? ? {headerGroup.headers.map(column => (
? ? ? ? ? ? ? <th {...column.getHeaderProps()}>{column.render("Header")}</th>
? ? ? ? ? ? ))}
? ? ? ? ? </tr>
? ? ? ? ))}
? ? ? </thead>
? ? ? <input
value={valueInput}
onChange={handleValueChange}
placeholder={"Busca pelo nome"}
/>
<> </>
? <CSVLink
? ? ? filename={"pesquisa_de_dados_tutorial.csv"}
? ? ? data={data}
? ? ? className="btn btn-primary">CSV
?</CSVLink>
?<> </>
?<Button onClick={handlePrint} type="primary" danger><FilePdfOutlined /> PDF </Button>
? ? ? <tbody {...getTableBodyProps()}>
? ? ? ? {rows.map((row, i) => {
? ? ? ? ? prepareRow(row);
? ? ? ? ? return (
? ? ? ? ? ? <tr {...row.getRowProps()}>
? ? ? ? ? ? ? {row.cells.map(cell => {
? ? ? ? ? ? ? ? return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
? ? ? ? ? ? ? })}
? ? ? ? ? ? </tr>
? ? ? ? ? );
? ? ? ? })}
? ? ? </tbody>
? ? </table>
? ? </div>
? );
}
export default Table;
Fim.