Repository: Desafio-Financeiro/meowcash-mobile
Pull request #19: Delete de transações
Author: login: IsabellaSoares
Created: 2025-03-09T20:59:43Z | Merged: 2025-03-09T21:54:38Z

<img width="307" alt="Captura de Tela 2025-03-09 às 17 50 40" src="https://github.com/user-attachments/assets/c96f6c3b-697e-4765-a642-29b09c710a2a" />
<img width="310" alt="Captura de Tela 2025-03-09 às 17 51 29" src="https://github.com/user-attachments/assets/b777eb6d-ea25-4b84-98c3-3956aa65a100" />
<img width="311" alt="Captura de Tela 2025-03-09 às 17 51 44" src="https://github.com/user-attachments/assets/46812484-5187-4f9f-898d-4ed6aa2d7717" />



Diff:
diff --git a/api/transaction/index.tsx b/api/transaction/index.tsx
index 842b9dd..4d3e2df 100644
--- a/api/transaction/index.tsx
+++ b/api/transaction/index.tsx
@@ -3,14 +3,16 @@ import { db } from "../../firebase/config";
 import {
   addDoc,
   collection,
+  doc,
   getDocs,
   limit,
   orderBy,
   query,
   startAfter,
+  updateDoc,
   where,
 } from "firebase/firestore";
-import { Transaction } from "@/components/Transactions/TransactionItem";
+import type { Transaction } from "@/components/transactions/TransactionItem";
 import { getBalance, updateBalance } from "../balance";
 
 const TRANSACTIONS_LIMIT = 6;
@@ -95,4 +97,35 @@ const addTransaction = async (transaction: Transaction) => {
   }
 };
 
-export { getTransactions, addTransaction };
+const deleteTransaction = async (transaction: Transaction) => {
+  try {
+    const transactionRef = doc(db, "transaction", transaction.id!);
+
+    await updateDoc(transactionRef, {
+      deletedAt: new Date().toISOString().split("T")[0],
+    });
+
+    const balance = await getBalance(transaction.userId);
+    const newBalance =
+      transaction.type === "Credit"
+        ? balance - transaction.value
+        : balance + transaction.value;
+
+    await updateBalance(transaction.userId, { balance: newBalance });
+
+    Toast.show({
+      type: "success",
+      text1: "Transação deletada com sucesso!",
+      position: "bottom",
+    });
+  } catch (error) {
+    console.error("Erro ao deletar transação: ", error);
+    Toast.show({
+      type: "error",
+      text1: "Erro ao deletar transação",
+      position: "bottom",
+    });
+  }
+};
+
+export { getTransactions, addTransaction, deleteTransaction };
diff --git a/app/(protected)/home/index.tsx b/app/(protected)/home/index.tsx
index 1992031..c710e94 100644
--- a/app/(protected)/home/index.tsx
+++ b/app/(protected)/home/index.tsx
@@ -20,6 +20,9 @@ export default function Home() {
     transactions,
     refetchTransactions,
     isLoading: transactionsIsLoading,
+    balanceIsLoading,
+    balance,
+    refetchBalance,
   } = useTransactions();
 
   const [transactionDate, setTransactionDate] = useState<{
@@ -31,16 +34,6 @@ export default function Home() {
   });
   const [transactionFilter, setTransactionFilter] = useState("");
 
-  const {
-    isLoading,
-    data,
-    refetch: refetchBalance,
-  } = useQuery({
-    queryKey: ["balanceInfo"],
-    queryFn: () => getBalance(user?.uid || ""),
-    enabled: !!user?.uid,
-  });
-
   return (
     <View style={styles.container}>
       <View>
@@ -48,14 +41,14 @@ export default function Home() {
         <Text style={styles.date}>{getFullCurrentDate()}</Text>
       </View>
 
-      <Balance balance={data} isLoading={isLoading} />
+      <Balance balance={balance} isLoading={balanceIsLoading} />
 
       <ScrollView>
         <View style={styles.summaryContainer}>
           <SummaryCard value={5000} type="income" />
           <SummaryCard value={2000} type="outcome" />
         </View>
-        
+
         <Button
           title="Criar transação de débito"
           variant="link"
@@ -93,15 +86,15 @@ export default function Home() {
           handleTransactionFilter={(filter) => setTransactionFilter(filter)}
         />
 
-          {transactionsIsLoading ? (
-            <ActivityIndicator
-              size="large"
-              color={theme.colors.primary60}
-              style={{ marginVertical: 24 }}
-            />
-          ) : (
-            <StaticTransactionsList data={transactions} />
-          )}
+        {transactionsIsLoading ? (
+          <ActivityIndicator
+            size="large"
+            color={theme.colors.primary60}
+            style={{ marginVertical: 24 }}
+          />
+        ) : (
+          <StaticTransactionsList data={transactions} />
+        )}
       </ScrollView>
     </View>
   );
diff --git a/components/DinamicList/index.tsx b/components/DinamicList/index.tsx
index b4bbfad..cc8cf97 100644
--- a/components/DinamicList/index.tsx
+++ b/components/DinamicList/index.tsx
@@ -16,16 +16,7 @@ const DinamicList = ({
   hasNextPage,
 }: DinamicListProps) => {
   return (
-    <View
-      style={{
-        // display: "flex",
-        // flexDirection: "column",
-        // justifyContent: "center",
-        alignItems: "center",
-        flex: 1,
-        // paddingBottom: 24,
-      }}
-    >
+    <View style={styles.screen}>
       <FlatList
         data={data}
         keyExtractor={(item) => item.id}
@@ -33,13 +24,15 @@ const DinamicList = ({
       />
 
       {hasNextPage && onLoadMore && (
-        <View style={{ width: "50%", marginTop: 24 }}>
-          <Button
-            variant="primary"
-            title={isLoading ? "Carregando..." : "Carregar mais"}
-            onPress={() => onLoadMore()}
-            disabled={isLoading}
-          />
+        <View style={styles.footer}>
+          <View style={styles.button}>
+            <Button
+              variant="primary"
+              title={isLoading ? "Carregando..." : "Carregar mais"}
+              onPress={() => onLoadMore()}
+              disabled={isLoading}
+            />
+          </View>
         </View>
       )}
     </View>
diff --git a/components/DinamicList/style.ts b/components/DinamicList/style.ts
index 0dc5eb2..de63488 100644
--- a/components/DinamicList/style.ts
+++ b/components/DinamicList/style.ts
@@ -1,13 +1,22 @@
 import { StyleSheet } from "react-native";
 
 export const styles = StyleSheet.create({
-  text: {
-    fontSize: 16,
-  },
   body: {
     paddingBottom: 15,
     paddingTop: 15,
     borderBottomWidth: 1,
     borderBottomColor: "#ccc",
   },
+  screen: {
+    display: "flex",
+    flexDirection: "column",
+    justifyContent: "center",
+    flex: 1,
+    paddingBottom: 24,
+  },
+  button: { width: "50%", marginHorizontal: "auto" },
+  footer: {
+    width: "100%",
+    marginTop: 24,
+  },
 });
diff --git a/components/transactions/DinamicTransactionsList/index.tsx b/components/transactions/DinamicTransactionsList/index.tsx
index 73f5eb3..82a5d4a 100644
--- a/components/transactions/DinamicTransactionsList/index.tsx
+++ b/components/transactions/DinamicTransactionsList/index.tsx
@@ -6,8 +6,13 @@ import { TransactionFilters } from "../filters";
 import { View } from "react-native";
 
 const DinamicTransactionsList = () => {
-  const { transactions, isLoading, fetchNextPage, hasNextPage } =
-    useTransactions();
+  const {
+    transactions,
+    isLoading,
+    fetchNextPage,
+    hasNextPage,
+    showDeleteAlert,
+  } = useTransactions();
   const [transactionsList, setTransactionsList] = useState<
     { id: string; body: React.ReactNode }[]
   >([]);
@@ -29,11 +34,15 @@ const DinamicTransactionsList = () => {
         return {
           id: transaction.id as string,
           body: (
-            <TransactionItem
-              transaction={transaction}
-              edit={() => {}}
-              exclude={() => {}}
-            />
+            <View style={{ width: "100%" }}>
+              <TransactionItem
+                transaction={transaction}
+                edit={() => {}}
+                exclude={() => {
+                  showDeleteAlert(transaction);
+                }}
+              />
+            </View>
           ),
         };
       }) || [];
@@ -48,7 +57,7 @@ const DinamicTransactionsList = () => {
   }, [isLoading, transactions]);
 
   return (
-    <View style={{ flex: 1 }}>
+    <>
       <View style={{ paddingHorizontal: 16 }}>
         <TransactionFilters
           handleTransactionDate={(date) => setTransactionDate(date)}
@@ -62,7 +71,7 @@ const DinamicTransactionsList = () => {
         isLoading={isLoading}
         hasNextPage={hasNextPage}
       />
-    </View>
+    </>
   );
 };
 
diff --git a/components/transactions/StaticTransactionsList/index.tsx b/components/transactions/StaticTransactionsList/index.tsx
index 072bd7f..8bd6ca6 100644
--- a/components/transactions/StaticTransactionsList/index.tsx
+++ b/components/transactions/StaticTransactionsList/index.tsx
@@ -5,9 +5,11 @@ import { styles } from "./style";
 import { View } from "react-native";
 import { Button } from "@/components/button";
 import { useNavigation } from "@react-navigation/native";
+import { useTransactions } from "@/context/TransactionsContext";
 
 const StaticTransactionsList = ({ data }: { data: Transaction[] }) => {
   const navigation = useNavigation();
+  const { showDeleteAlert } = useTransactions();
 
   return (
     <View>
@@ -16,7 +18,9 @@ const StaticTransactionsList = ({ data }: { data: Transaction[] }) => {
           <TransactionItem
             transaction={transaction}
             edit={() => {}}
-            exclude={() => {}}
+            exclude={() => {
+              showDeleteAlert(transaction);
+            }}
           />
         </View>
       ))}
diff --git a/components/transactions/TransactionItem/index.tsx b/components/transactions/TransactionItem/index.tsx
index 8f745fe..3e7f172 100644
--- a/components/transactions/TransactionItem/index.tsx
+++ b/components/transactions/TransactionItem/index.tsx
@@ -13,7 +13,7 @@ export interface TransactionModal extends Omit<Props, "transactionsList"> {
 export interface Props {
   transactionsList: Transaction[];
   edit: (id: Transaction["id"]) => void;
-  exclude: (id: Transaction["id"]) => void;
+  exclude: () => void;
 }
 
 export interface Transaction {
@@ -24,76 +24,86 @@ export interface Transaction {
   from?: string;
   to?: string;
   userId: string;
+  deletedAt?: string;
 }
 
-const TransactionItem = (transactionModal: TransactionModal) => {
-  const { edit, transaction, exclude } = transactionModal;
-  const { id, date, to, from, value, type } = transaction;
+const TransactionItem = ({ transaction, edit, exclude }: TransactionModal) => {
+  const { id, date, to, from, value, type, deletedAt } = transaction;
 
-  const styleValue = type === "Credit" ? styles.credit : styles.debit;
+  const styleValue = deletedAt
+    ? ""
+    : type === "Credit"
+    ? styles.credit
+    : styles.debit;
   const styleIcon = type === "Credit" ? styles.iconCredit : styles.iconDebit;
 
   return (
     <View style={styles.transaction}>
-      <View style={styles.title}>
-        <View style={{ ...styles.icon, ...styleIcon }}>
-          <MaterialCommunityIcons
-            name={type === "Credit" ? "trending-up" : "trending-down"}
-            size={26}
-            color={theme.colors.black}
-          />
-        </View>
-        <View style={styles.listTitle}>
-          <Text style={styles.font}>
-            {type === "Credit" ? "Entrada" : "Saida"}
-          </Text>
-          {type === "Credit" && from && (
-            <Text style={styles.colorText}>Origem: {from}</Text>
-          )}
-          {type === "Debit" && to && (
-            <Text style={styles.colorText}>Destino: {to}</Text>
-          )}
-        </View>
+      <View style={{ ...styles.icon, ...styleIcon }}>
+        <MaterialCommunityIcons
+          name={type === "Credit" ? "trending-up" : "trending-down"}
+          size={26}
+          color={theme.colors.black}
+        />
       </View>
-      <View style={styles.description}>
-        <View>
-          <Text style={styles.colorText}>
-            {format(new Date(`${date}T00:00:00`), "dd/MM/yyyy")}
-          </Text>
-          <Text style={{ ...styles.price, ...styleValue }}>
-            {"R$ " + formatCurrency(value)}
-          </Text>
-        </View>
-        <View style={styles.edit}>
-          <Button
-            variant={"ghost"}
-            style={styles.buttonTransaction}
-            onPress={() => {
-              edit(id);
-            }}
-            icon={
-              <MaterialCommunityIcons
-                size={12}
-                color={theme.colors.gray20}
-                name={"pencil"}
-              />
-            }
-          />
-          <Button
-            variant={"ghost"}
-            style={styles.buttonTransaction}
-            onPress={() => {
-              exclude(id);
-            }}
-            icon={
-              <MaterialCommunityIcons
-                size={12}
-                color={theme.colors.gray20}
-                name={"trash-can"}
-              />
-            }
-          />
+      <View style={styles.transactionData}>
+        <View style={styles.title}>
+          <View style={styles.listTitle}>
+            <Text style={styles.font}>
+              {type === "Credit" ? "Entrada" : "Saída"}
+            </Text>
+            {type === "Credit" && from && (
+              <Text style={styles.colorText}>Origem: {from}</Text>
+            )}
+            {type === "Debit" && to && (
+              <Text style={styles.colorText}>Destino: {to}</Text>
+            )}
+          </View>
         </View>
+        <Text
+          style={{
+            ...styles.price,
+            ...styleValue,
+            textDecorationLine: deletedAt ? "line-through" : undefined,
+          }}
+        >
+          R$ {formatCurrency(value)}
+        </Text>
+      </View>
+      <View>
+        <Text style={styles.colorText}>
+          {format(new Date(`${date}T00:00:00`), "dd/MM/yyyy")}
+        </Text>
+        {!deletedAt && (
+          <View style={styles.edit}>
+            <Button
+              variant={"ghost"}
+              style={styles.buttonTransaction}
+              onPress={() => {
+                edit(id);
+              }}
+              icon={
+                <MaterialCommunityIcons
+                  size={18}
+                  color={theme.colors.gray20}
+                  name={"pencil"}
+                />
+              }
+            />
+            <Button
+              variant={"ghost"}
+              style={styles.buttonTransaction}
+              onPress={() => exclude()}
+              icon={
+                <MaterialCommunityIcons
+                  size={18}
+                  color={theme.colors.gray20}
+                  name={"trash-can"}
+                />
+              }
+            />
+          </View>
+        )}
       </View>
     </View>
   );
diff --git a/components/transactions/TransactionItem/style.ts b/components/transactions/TransactionItem/style.ts
index 9d30205..04c02f6 100644
--- a/components/transactions/TransactionItem/style.ts
+++ b/components/transactions/TransactionItem/style.ts
@@ -7,14 +7,12 @@ export const styles = StyleSheet.create({
     flexDirection: "row",
     gap: 14,
     justifyContent: "space-between",
-    alignItems: "center",
     alignSelf: "stretch",
     borderTopColor: theme.colors.gray10,
     flexGrow: 1,
     fontFamily: theme.fonts.regular,
     padding: 12,
   },
-
   title: {
     display: "flex",
     justifyContent: "space-between",
@@ -22,58 +20,40 @@ export const styles = StyleSheet.create({
     alignItems: "center",
     gap: 15,
   },
-
   listTitle: {
     color: theme.colors.black,
     fontSize: 16,
     textOverflow: "ellipsis",
     overflow: "hidden",
+    gap: 4,
   },
   font: {
-    fontFamily: theme.fonts.regular,
+    fontFamily: theme.fonts.semibold,
+    fontSize: 16,
   },
   colorText: {
     color: theme.colors.text,
     fontFamily: theme.fonts.regular,
   },
-  description: {
-    display: "flex",
-    alignItems: "center",
-    gap: 14,
-    flexDirection: "row",
-  },
   edit: {
+    marginTop: 18,
     display: "flex",
-    flexDirection: "column",
-    alignItems: "flex-start",
-    gap: 4,
-  },
-
-  date: {
-    textAlign: "right",
-    color: theme.colors.text,
-    fontSize: 14,
-    fontFamily: theme.fonts.regular,
-    lineHeight: 24,
-    letterSpacing: 0.15,
+    flexDirection: "row",
+    gap: 12,
+    justifyContent: "flex-end",
   },
   price: {
     fontSize: 16,
-    fontStyle: "normal",
-    fontWeight: "600",
+    fontFamily: theme.fonts.semibold,
     lineHeight: 24,
     letterSpacing: 0.15,
-    textAlign: "right",
   },
-
   debit: {
     color: theme.colors.dangerDark,
   },
-
   credit: {
     color: theme.colors.successDark,
   },
-
   buttonTransaction: {
     padding: 6,
     borderRadius: 50,
@@ -81,8 +61,9 @@ export const styles = StyleSheet.create({
     borderColor: theme.colors.gray10,
     backgroundColor: theme.colors.white,
     color: theme.colors.gray20,
+    width: 40,
+    height: 40,
   },
-
   icon: {
     display: "flex",
     justifyContent: "center",
@@ -91,12 +72,17 @@ export const styles = StyleSheet.create({
     height: 42,
     borderRadius: 50,
   },
-
   iconCredit: {
     backgroundColor: theme.colors.success,
   },
-
   iconDebit: {
     backgroundColor: theme.colors.danger,
   },
+  transactionData: {
+    display: "flex",
+    flexDirection: "column",
+    flex: 1,
+    width: "100%",
+    justifyContent: "space-between",
+  },
 });
diff --git a/context/AuthContext.tsx b/context/AuthContext.tsx
index fbcd654..c5d44bb 100644
--- a/context/AuthContext.tsx
+++ b/context/AuthContext.tsx
@@ -33,11 +33,6 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
       );
       setUser(userCredential.user);
       setIsAuthenticated(true);
-      Toast.show({
-        type: "success",
-        text1: "Usuário logado com sucesso",
-        position: "bottom",
-      });
       navigation.navigate("Home" as never);
       return true;
     } catch (error) {
diff --git a/context/TransactionsContext.tsx b/context/TransactionsContext.tsx
index e73817e..7a3e1d2 100644
--- a/context/TransactionsContext.tsx
+++ b/context/TransactionsContext.tsx
@@ -1,4 +1,4 @@
-import type { Transaction } from "@/components/Transactions/TransactionItem";
+import type { Transaction } from "@/components/transactions/TransactionItem";
 import {
   createContext,
   ReactNode,
@@ -16,11 +16,15 @@ import {
   useInfiniteQuery,
   useQuery,
 } from "@tanstack/react-query";
-import { getTransactions } from "@/api/transaction";
+import { deleteTransaction, getTransactions } from "@/api/transaction";
+import { Alert } from "react-native";
+import { getBalance } from "@/api/balance";
 
 interface ITransactionsContext {
+  balance: number;
   transactions: Transaction[];
   isLoading: boolean;
+  balanceIsLoading: boolean;
   hasNextPage: boolean;
   fetchNextPage: (options?: FetchNextPageOptions) => Promise<
     InfiniteQueryObserverResult<
@@ -48,6 +52,10 @@ interface ITransactionsContext {
       Error
     >
   >;
+  refetchBalance: (
+    options?: RefetchOptions
+  ) => Promise<QueryObserverResult<any, Error>>;
+  showDeleteAlert: (transaction: Transaction) => void;
 }
 
 const TransactionsContext = createContext<ITransactionsContext | undefined>(
@@ -58,6 +66,17 @@ export const TransactionsProvider = ({ children }: { children: ReactNode }) => {
   const { user } = useAuth();
   const [transactions, setTransactions] = useState<Transaction[]>([]);
 
+  const {
+    isLoading: balanceIsLoading,
+    data: balance,
+    refetch: refetchBalance,
+    isRefetching: balanceIsRefetching,
+  } = useQuery({
+    queryKey: ["balanceInfo"],
+    queryFn: () => getBalance(user?.uid || ""),
+    enabled: !!user?.uid,
+  });
+
   const {
     data,
     isLoading,
@@ -77,6 +96,29 @@ export const TransactionsProvider = ({ children }: { children: ReactNode }) => {
     enabled: !!user?.uid,
   });
 
+  const showDeleteAlert = (transaction: Transaction) => {
+    Alert.alert(
+      "Deletar transação",
+      "Tem certeza de que deseja deletar esta transação?",
+      [
+        {
+          text: "Cancelar",
+          onPress: () => {},
+          style: "cancel",
+        },
+        {
+          text: "Deletar",
+          onPress: () => {
+            deleteTransaction(transaction).then(() => {
+              refetch();
+              refetchBalance();
+            });
+          },
+        },
+      ]
+    );
+  };
+
   useEffect(() => {
     if (!isLoading && data?.pages[0]) {
       setTransactions(
@@ -88,11 +130,15 @@ export const TransactionsProvider = ({ children }: { children: ReactNode }) => {
   return (
     <TransactionsContext.Provider
       value={{
+        balance,
         transactions,
         isLoading: isLoading || isFetchingNextPage || isRefetching,
+        balanceIsLoading: balanceIsLoading || balanceIsRefetching,
         fetchNextPage,
         hasNextPage,
         refetchTransactions: refetch,
+        refetchBalance,
+        showDeleteAlert,
       }}
     >
       {children}


Reviews:
user: login: IsabellaSoares
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-09T21:01:25Z
user: login: crisgon
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-09T21:08:31Z
user: login: crisgon
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-09T21:16:04Z
user: login: IsabellaSoares
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-09T21:27:46Z
user: login: crisgon
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-09T21:54:12Z

Review comments:
diff_hunk: @@ -77,6 +96,29 @@ export const TransactionsProvider = ({ children }: { children: ReactNode }) => {
     enabled: !!user?.uid,
   });
 
+  const showDeleteAlert = (transaction: Transaction) => {
+    Alert.alert(
path: context/TransactionsContext.tsx
user: login: IsabellaSoares
body: Alert temporário até substituirmos pelo Dialog
created_at: 2025-03-09T21:01:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -77,6 +96,29 @@ export const TransactionsProvider = ({ children }: { children: ReactNode }) => {
     enabled: !!user?.uid,
   });
 
+  const showDeleteAlert = (transaction: Transaction) => {
+    Alert.alert(
path: context/TransactionsContext.tsx
user: login: crisgon
body: N achei ruim o alert. No android ficou bom
created_at: 2025-03-09T21:08:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -77,6 +96,29 @@ export const TransactionsProvider = ({ children }: { children: ReactNode }) => {
     enabled: !!user?.uid,
   });
 
+  const showDeleteAlert = (transaction: Transaction) => {
+    Alert.alert(
path: context/TransactionsContext.tsx
user: login: crisgon
body: Pra mim criar um alert de confirm só pra isso vai ser uma perda de tempo por agora.

created_at: 2025-03-09T21:16:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -77,6 +96,29 @@ export const TransactionsProvider = ({ children }: { children: ReactNode }) => {
     enabled: !!user?.uid,
   });
 
+  const showDeleteAlert = (transaction: Transaction) => {
+    Alert.alert(
path: context/TransactionsContext.tsx
user: login: IsabellaSoares
body: Mas não precisa criar um alert de confirmação. A minha ideia é passar esse conteúdo para um Dialog quando o componente estiver pronto. Eu só coloquei esse Alert nativo porque foi o jeito mais rápido que pensei pra fazer o fluxo.
created_at: 2025-03-09T21:27:46Z
author_association: CONTRIBUTOR

PR comments:
user: login: crisgon
created_at: 2025-03-09T21:12:16Z
body: N tem como colocar algum loading indicando que está deletando? Senti a sensação de que a ação n estava sendo feita.

Algo assim. 

![image](https://github.com/user-attachments/assets/59cfffba-0229-443e-8858-68dab65b9897)

author_association: CONTRIBUTOR
user: login: IsabellaSoares
created_at: 2025-03-09T21:28:34Z
body: > N tem como colocar algum loading indicando que está deletando? Senti a sensação de que a ação n estava sendo feita.
> 
> Algo assim.
> 
> ![image](https://private-user-images.githubusercontent.com/11144937/420705508-59cfffba-0229-443e-8858-68dab65b9897.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE1NTU3MzcsIm5iZiI6MTc0MTU1NTQzNywicGF0aCI6Ii8xMTE0NDkzNy80MjA3MDU1MDgtNTljZmZmYmEtMDIyOS00NDNlLTg4NTgtNjhkYWI2NWI5ODk3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMDklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzA5VDIxMjM1N1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWExNmI5MjVlNzRlYmUwOWQ5NDdmMGVlZGRiZjEzM2Y0OTg0MjQ2NmVkZmZjZjE2YTkzYTI2NzQyZjM4MjQwMTAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.3G9JE-Uh2dE236kE3FQ6TI3Re6w6CXRZHwULzQiIljI)

Acho que dá sim, mas como a ideia é colocar esse conteúdo no componente de Dialog quando estiver pronto, poderíamos usar o state loading do Botão que já temos, o que acha?
author_association: CONTRIBUTOR
user: login: crisgon
created_at: 2025-03-09T21:34:22Z
body: > > N tem como colocar algum loading indicando que está deletando? Senti a sensação de que a ação n estava sendo feita.
> > Algo assim.
> > ![image](https://private-user-images.githubusercontent.com/11144937/420705508-59cfffba-0229-443e-8858-68dab65b9897.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDE1NTU3MzcsIm5iZiI6MTc0MTU1NTQzNywicGF0aCI6Ii8xMTE0NDkzNy80MjA3MDU1MDgtNTljZmZmYmEtMDIyOS00NDNlLTg4NTgtNjhkYWI2NWI5ODk3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMDklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzA5VDIxMjM1N1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWExNmI5MjVlNzRlYmUwOWQ5NDdmMGVlZGRiZjEzM2Y0OTg0MjQ2NmVkZmZjZjE2YTkzYTI2NzQyZjM4MjQwMTAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.3G9JE-Uh2dE236kE3FQ6TI3Re6w6CXRZHwULzQiIljI)
> 
> Acho que dá sim, mas como a ideia é colocar esse conteúdo no componente de Dialog quando estiver pronto, poderíamos usar o state loading do Botão que já temos, o que acha?


Falei do loading assim pensando em usar o alert do próprio OS mesmo. Sem precisar criar um personalizado.
Mas podemos seguir como vc falou.
author_association: CONTRIBUTOR