账单详情页面

This commit is contained in:
2025-09-26 17:32:34 +08:00
parent 9ba0b8eb8a
commit d3ceda66d6
8 changed files with 836 additions and 88 deletions

View File

@@ -29,6 +29,7 @@ export default defineAppConfig({
"queryTransactions/index", // 查询交易
"downloadBill/index", // 下载账单
"downloadBillRecords/index", // 下载账单记录
"billDetail/index", // 账单详情
],
},
// {

View File

@@ -0,0 +1,3 @@
export default definePageConfig({
navigationBarTitleText: '明细详情',
})

View File

@@ -0,0 +1,56 @@
.bill-detail-page {
min-height: 100vh;
background-color: #f5f5f5;
padding: 5px;
.title-text-box {
height: 118px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 16px;
.title-text {
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 12px;
text-align: center;
}
.amount-text {
font-family: DingTalk JinBuTi;
font-weight: 400;
font-style: Regular;
font-size: 32px;
vertical-align: middle;
text-align: center;
}
}
.detail-wrapper {
padding: 12px 20px 16px;
border: 0.5px solid #ebebeb;
box-shadow: 0px 4px 36px 0px #0000000d;
.detail-item {
display: flex;
justify-content: space-between;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 12px;
line-height: 18px;
color: #000;
margin-bottom: 8px;
& > Text {
&:first-child {
color: #3c3c4399;
}
}
.with-btn-box {
display: flex;
gap: 8px;
.btn {
color: #007aff;
}
}
}
}
}

View File

@@ -0,0 +1,65 @@
import React, { useEffect, useState } from "react";
import { View, Text, Input, Button, Image } from "@tarojs/components";
import { TransactionType, TransactionSubType } from "@/user_pages/wallet/index";
import "./index.scss";
enum FreezeActions {
Unfreeze = "unfreeze",
Freeze = "freeze",
}
interface BillDetail {
id: number;
transaction_type: TransactionType;
transaction_sub_type: TransactionSubType;
freeze_action: FreezeActions;
amount: number;
description: string;
related_id: number;
create_time: string;
order_no: string;
game_title: string;
order_amount: number;
type_text: string;
sub_type_text: string;
amount_yuan: string;
}
const BillDetail: React.FC = () => {
const [billDetail, setBillDetail] = useState<BillDetail | null>(null);
return (
<View className="bill-detail-page">
<View className="title-text-box">
<View className="title-text"> ()</View>
<View className="amount-text">
<Text>+</Text>
<Text>65.00</Text>
</View>
</View>
<View className="detail-wrapper">
<View className="detail-item">
<Text></Text>
<Text>2025-02-16 12:21:54</Text>
</View>
<View className="detail-item">
<Text></Text>
<Text></Text>
</View>
<View className="detail-item">
<Text></Text>
<Text>¥3890.00</Text>
</View>
<View className="detail-item">
<Text></Text>
<View className="with-btn-box">
<Text>89172371293791273912</Text>
<Text className="btn"></Text>
</View>
</View>
</View>
</View>
);
};
export default BillDetail;

View File

@@ -1,3 +1,3 @@
export default definePageConfig({
navigationBarTitleText: '下载记录',
navigationBarTitleText: '查找交易',
})

View File

@@ -0,0 +1,197 @@
.listSearchContainer {
padding: 0 15px;
padding-top: 16px;
.icon16 {
width: 16px;
height: 16px;
}
.topSearch {
padding: 10px 16px 5px 12px;
display: flex;
align-items: center;
height: 44px;
box-sizing: border-box;
gap: 10px;
border-radius: 44px;
border: 0.5px solid rgba(0, 0, 0, 0.06);
background: #fff;
box-shadow: 0 4px 48px 0 rgba(0, 0, 0, 0.08);
.nut-input {
padding: 0;
height: 100%;
}
}
.searchRight {
display: flex;
align-items: center;
gap: 12px;
.searchLine {
width: 1px;
height: 20px;
border-radius: 20px;
background: rgba(0, 0, 0, 0.06);
}
.searchText {
color: #000000;
font-size: 16px;
font-weight: 600;
line-height: 20px;
}
}
.searchIcon {
width: 20px;
height: 20px;
}
.historySearchTitleWrapper {
display: flex;
padding: 12px 15px;
justify-content: space-between;
align-items: flex-end;
align-self: stretch;
.historySearchTitle,
.historySearchClear {
color: #000;
font-size: 14px;
font-weight: 600;
line-height: 20px;
}
.historySearchClear {
color: #9a9a9a;
display: flex;
align-items: center;
gap: 4px;
}
}
.historySearchList {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
.historySearchItem {
flex-shrink: 0;
flex-grow: 0;
display: flex;
height: 28px;
padding: 4px 12px;
justify-content: center;
align-items: center;
gap: 2px;
border-radius: 999px;
border: 0.5px solid rgba(0, 0, 0, 0.06);
background: rgba(0, 0, 0, 0.03);
}
}
.searchSuggestion {
padding: 6px 0;
.searchSuggestionItem {
padding: 10px 20px;
display: flex;
align-items: center;
justify-content: space-between;
.searchSuggestionItemLeft {
display: flex;
align-items: center;
gap: 12px;
color: rgba(60, 60, 67, 0.6);
font-size: 14px;
font-weight: 400;
line-height: 20px;
}
.highlight {
color: #000000;
}
}
}
.transaction_list {
.loading_state,
.empty_state {
padding: 40px 20px;
text-align: center;
.loading_text,
.empty_text {
font-size: 14px;
color: #999;
}
}
.transaction_item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 20px;
.transaction_left {
display: flex;
flex-direction: column;
gap: 4px;
flex: 1;
.transaction_title {
font-size: 12px;
font-weight: 600;
color: #000;
line-height: 1.5;
text-align: left;
}
.transaction_time {
display: flex;
align-items: center;
align-self: stretch;
gap: 4px;
.transaction_date,
.transaction_clock {
font-size: 10px;
font-weight: 400;
color: rgba(60, 60, 67, 0.6);
line-height: 1.2;
text-align: left;
}
}
}
.transaction_right {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
width: 68px;
.transaction_amount {
font-size: 12px;
font-weight: 600;
color: #000;
line-height: 1.5;
text-align: right;
}
.balance_info {
font-size: 10px;
font-weight: 400;
color: rgba(60, 60, 67, 0.6);
line-height: 1.2;
text-align: right;
}
}
}
}
}

View File

@@ -1,10 +1,348 @@
import React, { useState, useEffect } from "react";
import { View } from "@tarojs/components";
import { useState } from "react";
import { View, Image, Text } from "@tarojs/components";
import { Input } from "@nutui/nutui-react-taro";
import { useEffect, useRef } from "react";
import img from "@/config/images";
import { withAuth } from "@/components";
import "./index.scss";
import httpService from "@/services/httpService";
import Taro from "@tarojs/taro";
interface Transaction {
id: number;
user_id: number;
transaction_type: string;
freeze_action: string | null;
amount: string;
description: string;
create_time: string;
last_modify_time: string;
related_id: number;
}
// 钱包信息类型
interface WalletInfo {
balance: number;
frozen_balance?: number;
total_balance?: number;
total_income?: number;
total_withdraw?: number;
}
interface History {
id: number;
keyword: string;
}
interface TransactionLoadParams {
page: number;
limit: number;
keyword?: string;
}
const QueryTransactions = () => {
const [loading_transactions, set_loading_transactions] = useState(false);
const [transactions, setTransactions] = useState<Transaction[]>([]);
const [searchHistory, setSearchHistory] = useState<History[]>([]);
const ref = useRef<any>(null);
const [load_transactions_params, set_load_transactions_params] =
useState<TransactionLoadParams>({
page: 1,
limit: 20,
keyword: "",
});
useEffect(() => {
getSearchHistory();
return () => {
handleClear();
};
}, []);
useEffect(() => {
if (ref?.current) {
ref.current.focus();
}
}, [ref.current]);
// 是否显示清空图标
const isShowClearIcon =
load_transactions_params.keyword &&
load_transactions_params.keyword?.length > 0;
const getSearchHistory = async () => {
try {
const response = await httpService.post("/wallet/search_history", {
limit: 10,
});
if (response && response.data) {
setSearchHistory(response.data);
}
} catch (e) {
console.error(e);
}
};
/**
* @description 输入
* @param value
*/
const handleChange = (value: string) => {
set_load_transactions_params((prev) => {
return { ...prev, keyword: value };
});
};
/**
* @description 点击清空输入内容
*/
const handleClear = () => {
setTransactions([]);
set_load_transactions_params((prev) => {
return { ...prev, keyword: "" };
});
};
/**
* @description 点击历史搜索
* @param value
*/
const handleHistoryClick = (item: { id: number; keyword: string }) => {
set_load_transactions_params((prev) => {
handleSearch(item?.keyword);
return { ...prev, keyword: item?.keyword };
});
};
/**
* @description 清空历史搜索
*/
const handleClearHistory = async () => {
await httpService.post("/wallet/clear_search_history");
setSearchHistory([]);
};
/**
* @description 点击搜索
*/
const handleSearch = async (val?: string) => {
if (!val) {
return;
}
set_loading_transactions(true);
try {
const response = await httpService.post("/wallet/transactions", {
...load_transactions_params,
keyword: val,
});
console.log("交易记录响应:", response);
if (response && response.data && response.data.list) {
setTransactions(response.data.list);
} else {
setTransactions([]);
}
} catch (error) {
setTransactions([]);
let errorMessage = "加载交易记录失败";
if (
error &&
error.response &&
error.response.data &&
error.response.data.message
) {
errorMessage = error.response.data.message;
} else if (error && error.data && error.data.message) {
errorMessage = error.data.message;
}
Taro.showToast({
title: errorMessage,
icon: "error",
duration: 2000,
});
} finally {
set_loading_transactions(false);
}
};
// 格式化金额显示
const format_amount = (amount: number | string) => {
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
return numAmount.toFixed(2);
};
// 钱包信息状态
const [wallet_info, set_wallet_info] = useState<WalletInfo>({
balance: 0,
});
// 格式化时间显示
const format_time = (time: string) => {
const date = new Date(time);
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return {
date: `2025-${month}-${day}`,
time: `${hours}:${minutes}:${seconds}`,
};
};
// 获取交易类型文字
const get_transaction_type_text = (transaction: Transaction) => {
// 如果有描述信息,优先使用描述
if (transaction.description) {
return transaction.description;
}
const typeMap: { [key: string]: string } = {
income: "收入",
expense: "支出",
freeze: "冻结",
unfreeze: "解冻",
};
let typeText =
typeMap[transaction.transaction_type] || transaction.transaction_type;
// 如果有冻结操作,添加到类型文字中
if (transaction.freeze_action) {
const freezeMap: { [key: string]: string } = {
freeze: "冻结",
unfreeze: "解冻",
};
typeText += `(${freezeMap[transaction.freeze_action]})`;
}
return typeText;
};
const navigateToDetail = (id: number) => {
Taro.navigateTo({
url: `/user_pages/billDetail/index?id=${id}`,
});
};
// 获取金额显示(带符号)
const get_amount_display = (transaction: Transaction) => {
const isPositive = transaction.transaction_type === "income";
const prefix = isPositive ? "+" : "-";
return `${prefix}${format_amount(transaction.amount)}`;
};
const QueryTransactions: React.FC = () => {
return (
<View></View>
<>
<View className="listSearchContainer">
{/* 搜索 */}
<View className="topSearch">
<Image className="searchIcon" src={img.ICON_LIST_SEARCH_SEARCH} />
<Input
placeholder="查找"
value={load_transactions_params.keyword}
defaultValue={load_transactions_params.keyword}
onChange={handleChange}
onClear={handleClear}
autoFocus
clearable={false}
ref={ref}
/>
<View className="searchRight">
{isShowClearIcon && (
<Image
className="clearIcon icon16"
src={img.ICON_LIST_SEARCH_CLEAR}
onClick={handleClear}
/>
)}
<View className="searchLine" />
<Text
className="searchText"
onClick={() => handleSearch(load_transactions_params.keyword)}
>
</Text>
</View>
</View>
{/* 查找历史 */}
{!isShowClearIcon && searchHistory.length > 0 && (
<View className="historySearch">
<View className="historySearchTitleWrapper">
<View className="historySearchTitle"></View>
<View className="historySearchClear" onClick={handleClearHistory}>
<Text></Text>
<Image
className="clearIcon icon16"
src={img.ICON_LIST_SEARCH_CLEAR_HISTORY}
/>
</View>
</View>
{searchHistory.length && (
<View className="historySearchList">
{(searchHistory || [])?.map((item) => {
if (!item?.keyword) {
return null;
}
return (
<Text
className="historySearchItem"
onClick={() => handleHistoryClick(item)}
>
{item?.keyword}
</Text>
);
})}
</View>
)}
</View>
)}
{/* 交易记录列表 */}
<View className="transaction_list">
{loading_transactions ? (
<View className="loading_state">
<Text className="loading_text">...</Text>
</View>
) : transactions.length > 0 ? (
transactions.map((transaction) => {
const timeInfo = format_time(transaction.create_time);
return (
<View
key={transaction.id}
className="transaction_item"
onClick={() => {
navigateToDetail(transaction.id);
}}
>
<View className="transaction_left">
<Text className="transaction_title">
{get_transaction_type_text(transaction)}
</Text>
<View className="transaction_time">
<Text className="transaction_date">{timeInfo.date}</Text>
<Text className="transaction_clock">{timeInfo.time}</Text>
</View>
</View>
<View className="transaction_right">
<Text className="transaction_amount">
{get_amount_display(transaction)}
</Text>
<Text className="balance_info">
¥{format_amount(wallet_info.balance)}
</Text>
</View>
</View>
);
})
) : (
<View className="empty_state">
<Text className="empty_text"></Text>
</View>
)}
</View>
</View>
</>
);
};
export default QueryTransactions;
export default withAuth(QueryTransactions);

View File

@@ -28,18 +28,18 @@ interface WalletInfo {
total_withdraw?: number;
}
enum TransactionType {
All = '',
Income = 'income',
Expense = 'expense',
export enum TransactionType {
All = "",
Income = "income",
Expense = "expense",
}
enum TransactionSubType {
All = '',
GameActivity = 'game_activity',
Withdrawal = 'withdrawal',
Refund = 'refund',
Compensation = 'compensation',
export enum TransactionSubType {
All = "",
GameActivity = "game_activity",
Withdrawal = "withdrawal",
Refund = "refund",
Compensation = "compensation",
}
interface TransactionLoadParams {
@@ -57,43 +57,42 @@ interface Option<T> {
const income_expense_options: Option<TransactionType>[] = [
{
label: '全部',
value: TransactionType.All
label: "全部",
value: TransactionType.All,
},
{
label: '支出',
value: TransactionType.Expense
label: "支出",
value: TransactionType.Expense,
},
{
label: '收入',
value: TransactionType.Income
label: "收入",
value: TransactionType.Income,
},
];
const transaction_type_options: Option<TransactionSubType>[] = [
{
label: '全部',
value: TransactionSubType.All
label: "全部",
value: TransactionSubType.All,
},
{
label: '组织活动',
value: TransactionSubType.GameActivity
label: "组织活动",
value: TransactionSubType.GameActivity,
},
{
label: '提现',
value: TransactionSubType.Withdrawal
label: "提现",
value: TransactionSubType.Withdrawal,
},
{
label: '退款',
value: TransactionSubType.Refund
label: "退款",
value: TransactionSubType.Refund,
},
{
label: '企业赔付',
value: TransactionSubType.Compensation
label: "企业赔付",
value: TransactionSubType.Compensation,
},
];
const WalletPage: React.FC = () => {
// 钱包信息状态
const [wallet_info, set_wallet_info] = useState<WalletInfo>({
@@ -112,14 +111,15 @@ const WalletPage: React.FC = () => {
// 交易记录过滤状态
const [showFilterPopup, setShowFilterPopup] = useState(false);
const [load_transactions_params, set_load_transactions_params] = useState<TransactionLoadParams>({
page: 1,
limit: 20,
type: TransactionType.All,
transaction_sub_type: TransactionSubType.All,
keyword: "",
date: ""
});
const [load_transactions_params, set_load_transactions_params] =
useState<TransactionLoadParams>({
page: 1,
limit: 20,
type: TransactionType.All,
transaction_sub_type: TransactionSubType.All,
keyword: "",
date: "",
});
// 页面显示时加载数据
useDidShow(() => {
@@ -131,19 +131,30 @@ const WalletPage: React.FC = () => {
const load_wallet_data = async () => {
try {
const response = await httpService.post("/wallet/balance");
const { balance, frozen_balance, total_balance, total_income, total_withdraw } = response.data;
const {
balance,
frozen_balance,
total_balance,
total_income,
total_withdraw,
} = response.data;
set_wallet_info({
balance,
frozen_balance,
total_balance,
total_income,
total_withdraw
total_withdraw,
});
} catch (error: any) {
console.error("加载钱包数据失败:", error);
let errorMessage = "加载失败,请重试";
if (error && error.response && error.response.data && error.response.data.message) {
if (
error &&
error.response &&
error.response.data &&
error.response.data.message
) {
errorMessage = error.response.data.message;
} else if (error && error.data && error.data.message) {
errorMessage = error.data.message;
@@ -165,7 +176,9 @@ const WalletPage: React.FC = () => {
set_loading_transactions(true);
console.log("开始加载交易记录...");
const response = await httpService.post("/wallet/transactions", { ...load_transactions_params });
const response = await httpService.post("/wallet/transactions", {
...load_transactions_params,
});
console.log("交易记录响应:", response);
@@ -181,7 +194,12 @@ const WalletPage: React.FC = () => {
set_transactions([]);
let errorMessage = "加载交易记录失败";
if (error && error.response && error.response.data && error.response.data.message) {
if (
error &&
error.response &&
error.response.data &&
error.response.data.message
) {
errorMessage = error.response.data.message;
} else if (error && error.data && error.data.message) {
errorMessage = error.data.message;
@@ -231,13 +249,12 @@ const WalletPage: React.FC = () => {
return;
}
set_submitting(true);
// 先调用后端接口获取提现参数
const response = await httpService.post("/wallet/withdraw", {
amount: parseFloat(withdraw_amount),
transfer_remark: "用户申请提现"
transfer_remark: "用户申请提现",
});
// 根据后端返回的数据结构解析参数
@@ -268,31 +285,28 @@ const WalletPage: React.FC = () => {
},
fail: (res) => {
console.log("微信转账失败:", res);
}
},
});
};
// 格式化金额显示
const format_amount = (amount: number | string) => {
const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount;
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
return numAmount.toFixed(2);
};
// 格式化时间显示
const format_time = (time: string) => {
const date = new Date(time);
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return {
date: `2025-${month}-${day}`,
time: `${hours}:${minutes}:${seconds}`
time: `${hours}:${minutes}:${seconds}`,
};
};
@@ -304,19 +318,20 @@ const WalletPage: React.FC = () => {
}
const typeMap: { [key: string]: string } = {
'income': '收入',
'expense': '支出',
'freeze': '冻结',
'unfreeze': '解冻'
income: "收入",
expense: "支出",
freeze: "冻结",
unfreeze: "解冻",
};
let typeText = typeMap[transaction.transaction_type] || transaction.transaction_type;
let typeText =
typeMap[transaction.transaction_type] || transaction.transaction_type;
// 如果有冻结操作,添加到类型文字中
if (transaction.freeze_action) {
const freezeMap: { [key: string]: string } = {
'freeze': '冻结',
'unfreeze': '解冻'
freeze: "冻结",
unfreeze: "解冻",
};
typeText += `(${freezeMap[transaction.freeze_action]})`;
}
@@ -326,14 +341,14 @@ const WalletPage: React.FC = () => {
// 获取金额显示(带符号)
const get_amount_display = (transaction: Transaction) => {
const isPositive = transaction.transaction_type === 'income';
const prefix = isPositive ? '+' : '-';
const isPositive = transaction.transaction_type === "income";
const prefix = isPositive ? "+" : "-";
return `${prefix}${format_amount(transaction.amount)}`;
};
const show_filter_popup = () => {
setShowFilterPopup(true)
}
setShowFilterPopup(true);
};
return (
<View className="wallet_page">
@@ -351,15 +366,24 @@ const WalletPage: React.FC = () => {
<View className="amount_container">
<Text className="currency_symbol">¥</Text>
<View className="amount_group">
<Text className="main_amount">{Math.floor(wallet_info.balance)}</Text>
<Text className="decimal_amount">.{((wallet_info.balance % 1) * 100).toFixed(0).padStart(2, '0')}</Text>
<Text className="main_amount">
{Math.floor(wallet_info.balance)}
</Text>
<Text className="decimal_amount">
.
{((wallet_info.balance % 1) * 100)
.toFixed(0)
.padStart(2, "0")}
</Text>
</View>
</View>
<Button className="withdraw_btn" onClick={handle_withdraw}>
</Button>
</View>
<Text className="available_amount">¥{format_amount(wallet_info.balance)}</Text>
<Text className="available_amount">
¥{format_amount(wallet_info.balance)}
</Text>
</View>
</View>
@@ -367,18 +391,40 @@ const WalletPage: React.FC = () => {
<View className="function_buttons">
<View className="function_item" onClick={show_filter_popup}>
<Text className="function_text"></Text>
<Image className="function_icon" src={require("@/static/wallet/arrow-down.svg")} />
<Image
className="function_icon"
src={require("@/static/wallet/arrow-down.svg")}
/>
</View>
<View className="function_item" onClick={() => Taro.navigateTo({ url: "/user_pages/queryTransactions/index" })}>
<Image className="function_icon" src={require("@/static/wallet/search.svg")} />
<View
className="function_item"
onClick={() =>
Taro.navigateTo({ url: "/user_pages/queryTransactions/index" })
}
>
<Image
className="function_icon"
src={require("@/static/wallet/search.svg")}
/>
<Text className="function_text"></Text>
</View>
<View className="function_item" onClick={() => Taro.navigateTo({ url: "/user_pages/downloadBill/index" })}>
<Image className="function_icon" src={require("@/static/wallet/download.svg")} />
<View
className="function_item"
onClick={() =>
Taro.navigateTo({ url: "/user_pages/downloadBill/index" })
}
>
<Image
className="function_icon"
src={require("@/static/wallet/download.svg")}
/>
<Text className="function_text"></Text>
</View>
<View className="function_item">
<Image className="function_icon" src={require("@/static/wallet/custom-service.svg")} />
<Image
className="function_icon"
src={require("@/static/wallet/custom-service.svg")}
/>
<Text className="function_text"></Text>
</View>
</View>
@@ -403,7 +449,15 @@ const WalletPage: React.FC = () => {
transactions.map((transaction) => {
const timeInfo = format_time(transaction.create_time);
return (
<View key={transaction.id} className="transaction_item">
<View
key={transaction.id}
className="transaction_item"
onClick={() => {
Taro.navigateTo({
url: `/user_pages/billDetail/index?id=${transaction.id}`,
});
}}
>
<View className="transaction_left">
<Text className="transaction_title">
{get_transaction_type_text(transaction)}
@@ -486,20 +540,54 @@ const WalletPage: React.FC = () => {
<View className="form_item">
<Text className="form_label"></Text>
<View className="options_wrapper">
{income_expense_options.map((option: Option<TransactionType>) => (
<View className={load_transactions_params.type === option.value ? "option_item active" : "option_item"} key={option.value} onClick={() => { set_load_transactions_params({ ...load_transactions_params, type: option.value }) }}>{option.label}</View>
))}
{income_expense_options.map(
(option: Option<TransactionType>) => (
<View
className={
load_transactions_params.type === option.value
? "option_item active"
: "option_item"
}
key={option.value}
onClick={() => {
set_load_transactions_params({
...load_transactions_params,
type: option.value,
});
}}
>
{option.label}
</View>
)
)}
</View>
</View>
<View className="form_item">
<Text className="form_label"></Text>
<View className="options_wrapper">
{transaction_type_options.map((option: Option<TransactionSubType>) => (
<View className={load_transactions_params.transaction_sub_type === option.value ? "option_item active" : "option_item"} key={option.value} onClick={() => { set_load_transactions_params({ ...load_transactions_params, transaction_sub_type: option.value }) }}>{option.label}</View>
))}
{transaction_type_options.map(
(option: Option<TransactionSubType>) => (
<View
className={
load_transactions_params.transaction_sub_type ===
option.value
? "option_item active"
: "option_item"
}
key={option.value}
onClick={() => {
set_load_transactions_params({
...load_transactions_params,
transaction_sub_type: option.value,
});
}}
>
{option.label}
</View>
)
)}
</View>
</View>
</View>
</View>
</CommonPopup>