diff --git a/code/allapp/allapp-go-v3/pkg/db/insert.go b/code/allapp/allapp-go-v3/pkg/db/insert.go
index b59ab098..4f63769b 100644
--- a/code/allapp/allapp-go-v3/pkg/db/insert.go
+++ b/code/allapp/allapp-go-v3/pkg/db/insert.go
@@ -31,11 +31,12 @@ func buildInsertSQL(table string, data map[string]any) (string, []any) {
}
func (c *Client) Insert(ctx context.Context, table, keyField string, data map[string]any) error {
-
- if _, err := validateData(table, keyField, data); err != nil {
+ if _, err := validateInsertData(table, keyField, data); err != nil {
return err
}
+ ensureID(data, keyField)
+
data = applyMetaFields(ctx, table, data, true)
sql, args := buildInsertSQL(table, data)
@@ -51,7 +52,7 @@ func (c *Client) BatchInsert(ctx context.Context, table, keyField string, list [
}
first := list[0]
- if _, err := validateData(table, keyField, first); err != nil {
+ if _, err := validateInsertData(table, keyField, first); err != nil {
return err
}
@@ -71,6 +72,7 @@ func (c *Client) BatchInsert(ctx context.Context, table, keyField string, list [
)
for _, row := range list {
+ ensureID(row, keyField)
row = applyMetaFields(ctx, table, row, true)
diff --git a/code/allapp/allapp-go-v3/pkg/db/validate.go b/code/allapp/allapp-go-v3/pkg/db/validate.go
index 41d04d3e..65829534 100644
--- a/code/allapp/allapp-go-v3/pkg/db/validate.go
+++ b/code/allapp/allapp-go-v3/pkg/db/validate.go
@@ -1,6 +1,7 @@
package db
import (
+ "allapp-go/pkg/uniqueid"
"fmt"
"regexp"
"strings"
@@ -58,3 +59,30 @@ func validateData(table string, keyField string, data map[string]any) (any, erro
return val, nil
}
+
+// 校验数据
+func validateInsertData(table string, keyField string, data map[string]any) (any, error) {
+ if table == "" {
+ return nil, fmt.Errorf("表名不能为空")
+ }
+
+ if len(data) == 0 {
+ return nil, fmt.Errorf("数据不能为空")
+ }
+
+ if keyField == "" {
+ return nil, fmt.Errorf("主键字段不能为空")
+ }
+
+ val, _ := data[keyField]
+
+ return val, nil
+}
+
+func ensureID(data map[string]any, keyField string) {
+ v, ok := data[keyField]
+
+ if !ok || v == nil || v == "" {
+ data[keyField] = uniqueid.NextId()
+ }
+}
diff --git a/code/allapp/allapp-rn/src/store/finance.ts b/code/allapp/allapp-rn/src/store/finance.ts
index 5b9ccf21..16a3d0bf 100644
--- a/code/allapp/allapp-rn/src/store/finance.ts
+++ b/code/allapp/allapp-rn/src/store/finance.ts
@@ -25,7 +25,7 @@ interface FinanceState {
records: FinanceRecordGroup[]
getTotalIncome: () => string
getTotalExpense: () => string
- getTotalBalance: () => string
+ getTotalBalance: () => string
setRecords: (records: FinanceRecord[]) => void
getRecordById: (id: number) => FinanceRecord | null
diff --git a/code/allapp/allapp-rn/test.html b/code/allapp/allapp-rn/test.html
index 7496c677..23d3bcd3 100644
--- a/code/allapp/allapp-rn/test.html
+++ b/code/allapp/allapp-rn/test.html
@@ -1,165 +1,118 @@
-
-
-
+
-
-
- 个人中心
+
+
+ 金额输入 Demo
-
+ /* 点击反馈 */
+ .amount-wrapper:active {
+ opacity: 0.6;
+ }
+ /* 隐藏输入 */
+ .hidden-input {
+ position: absolute;
+ opacity: 0;
+ pointer-events: none;
+ }
+
-
- ```
-
-
+
-
-
-
- 我的工具
- ›
-
-
- 数据管理
- ›
-
-
- 云同步
- ›
-
-
+
+
-
-
-
- 深色模式
- ›
-
-
- 通知设置
- ›
-
-
- 关于应用
- ›
-
-
- 退出登录
-
-
- ```
+
+
+
+
+
+
-
-
\ No newline at end of file
diff --git a/code/app/app-rn4/iconfont.json b/code/app/app-rn4/iconfont.json
index c49cfbc8..774f3e45 100644
--- a/code/app/app-rn4/iconfont.json
+++ b/code/app/app-rn4/iconfont.json
@@ -1,5 +1,5 @@
{
- "symbol_url": "//at.alicdn.com/t/c/font_5161133_jurut6g45n9.js",
+ "symbol_url": "//at.alicdn.com/t/c/font_5161133_p6e8mk9c4wd.js",
"use_typescript": true,
"save_dir": "./src/components/iconfont",
"trim_icon_prefix": "icon",
diff --git a/code/app/app-rn4/src/app/family/entry.tsx b/code/app/app-rn4/src/app/family/entry.tsx
index 6f445381..fe92fbee 100644
--- a/code/app/app-rn4/src/app/family/entry.tsx
+++ b/code/app/app-rn4/src/app/family/entry.tsx
@@ -84,11 +84,26 @@ export default function EntryFamily() {
const createInputRef = useRef(null);
useEffect(() => {
- if (familyStore.inFamily()) {
- toast.warning("你已经有家庭了");
+ const checkFamilyStatus = async () => {
+ // 从服务端获取最新状态,而非仅依赖本地缓存
+ const res = await loadDataApi({
+ view_name: "b_family_member",
+ search_condition: "user_id = ?",
+ search_columns: ["family_id"],
+ order_by: "",
+ args: [userStore.userInfo.id],
+ });
- router.replace("/home");
- }
+ if (res.isSuccess && res.data.length > 0) {
+ toast.success("你已经有家庭了");
+
+ familyStore.setCurrentFamily({ family_id: res.data[0].family_id });
+ router.replace("/(tabs)/home");
+ }
+ // 否则保持在 entry 页面
+ };
+
+ checkFamilyStatus();
}, []);
useEffect(() => {
@@ -190,37 +205,66 @@ export default function EntryFamily() {
const [familyId, memberId] = autoRes.data;
- const saveRes = await saveDataApi([
- {
- table_name: "b_family",
- key_field: "id",
- inserts: [
- {
- id: familyId,
- name: createForm.name,
- invite_code: inviteCode,
- owner_id: userStore.userInfo.id,
- },
- ],
- updates: [],
- deletes: [],
- },
- {
- table_name: "b_family_member",
- key_field: "id",
- inserts: [
- {
- id: memberId,
- family_id: familyId,
- user_id: userStore.userInfo.id,
- role: 0,
- nickname: userStore.userInfo.nickname,
- },
- ],
- updates: [],
- deletes: [],
- },
- ]);
+ const saveReq = [];
+
+ // 家庭
+ saveReq.push({
+ table_name: "b_family",
+ key_field: "id",
+ inserts: [
+ {
+ id: familyId,
+ name: createForm.name,
+ invite_code: inviteCode,
+ owner_id: userStore.userInfo.id,
+ },
+ ],
+ updates: [],
+ deletes: [],
+ });
+
+ // 家庭成员
+ saveReq.push({
+ table_name: "b_family_member",
+ key_field: "id",
+ inserts: [
+ {
+ id: memberId,
+ family_id: familyId,
+ user_id: userStore.userInfo.id,
+ role: 0,
+ nickname: userStore.userInfo.nickname,
+ },
+ ],
+ updates: [],
+ deletes: [],
+ });
+
+ // 默认记账分类
+ const defaultFinanceCategoryRes = await loadDataApi({
+ view_name: "b_finance_category_default",
+ search_condition: "",
+ order_by: "",
+ search_columns: ["name", "icon", "type", "sort_number"],
+ args: [],
+ });
+
+ if (!defaultFinanceCategoryRes.isSuccess) return;
+
+ defaultFinanceCategoryRes.data.forEach((item) => {
+ item.family_id = familyId;
+ });
+
+ // 默认记账分类
+ saveReq.push({
+ table_name: "b_finance_category",
+ key_field: "id",
+ inserts: defaultFinanceCategoryRes.data,
+ updates: [],
+ deletes: [],
+ });
+
+ const saveRes = await saveDataApi(saveReq);
if (saveRes.isSuccess) {
toast.success("创建成功");
diff --git a/code/app/app-rn4/src/app/finance/(tabs)/_layout.tsx b/code/app/app-rn4/src/app/finance/(tabs)/_layout.tsx
index 966d2011..92af433c 100644
--- a/code/app/app-rn4/src/app/finance/(tabs)/_layout.tsx
+++ b/code/app/app-rn4/src/app/finance/(tabs)/_layout.tsx
@@ -1,26 +1,49 @@
-import React from "react";
import { CircleDollarSignIcon, ChartNoAxesColumnIcon, PlusIcon } from "lucide-react-native";
import ModuleLayout from "@/layouts/ModuleLayout";
+import { useFinanceStore } from "@/store/finance";
+import { useEffect } from "react";
+import { loadDataApi } from "@/request/api";
const tabs = [
{
- id: "/money/home",
+ id: "/finance/home",
icon: CircleDollarSignIcon,
title: "记账",
},
{
- id: "/money/sub",
+ id: "/finance/add",
icon: PlusIcon,
isCenter: true,
},
{
- id: "/money/ana",
+ id: "/finance/analysis",
icon: ChartNoAxesColumnIcon,
title: "分析",
},
];
export default function Layout() {
+ const { setCategories, getCategories } = useFinanceStore();
+
+ useEffect(() => {
+ const categories = getCategories();
+ if (categories.length > 0) {
+ return;
+ }
+
+ loadDataApi({
+ view_name: "b_finance_category",
+ search_columns: [],
+ search_condition: ``,
+ order_by: "",
+ args: [],
+ }).then((res) => {
+ if (res.isSuccess) {
+ setCategories(res.data);
+ }
+ });
+ }, []);
+
return ;
}
diff --git a/code/app/app-rn4/src/app/finance/(tabs)/add/index.tsx b/code/app/app-rn4/src/app/finance/(tabs)/add/index.tsx
deleted file mode 100644
index 27d16f92..00000000
--- a/code/app/app-rn4/src/app/finance/(tabs)/add/index.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from "react";
-import { View, Text } from "react-native";
-
-export default function Add() {
- return (
-
- ADD
-
- );
-}
diff --git a/code/app/app-rn4/src/app/finance/(tabs)/ana/index.tsx b/code/app/app-rn4/src/app/finance/(tabs)/ana/index.tsx
deleted file mode 100644
index 2164df8f..00000000
--- a/code/app/app-rn4/src/app/finance/(tabs)/ana/index.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from "react";
-import { View, Text } from "react-native";
-
-export default function Ana() {
- return (
-
- Ana
-
- );
-}
\ No newline at end of file
diff --git a/code/app/app-rn4/src/app/finance/(tabs)/analysis/index.tsx b/code/app/app-rn4/src/app/finance/(tabs)/analysis/index.tsx
new file mode 100644
index 00000000..1c12e8bb
--- /dev/null
+++ b/code/app/app-rn4/src/app/finance/(tabs)/analysis/index.tsx
@@ -0,0 +1,46 @@
+import { ScrollShadow, Surface } from "heroui-native";
+import { LinearGradient } from "expo-linear-gradient";
+import { FlatList, ScrollView, Text, View } from "react-native";
+
+export default function ScrollShadowExample() {
+ const horizontalData = Array.from({ length: 10 }, (_, i) => ({
+ id: i,
+ title: `Card ${i + 1}`,
+ }));
+
+ return (
+
+ Horizontal List
+
+ (
+
+ {item.title}
+
+ )}
+ showsHorizontalScrollIndicator={false}
+ contentContainerClassName="p-5 gap-4"
+ />
+
+
+ Vertical Content
+
+
+ Long Content
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
+ incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
+ exercitation ullamco laboris.
+
+
+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
+ laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
+ architecto beatae vitae.
+
+
+
+
+ );
+}
diff --git a/code/app/app-rn4/src/app/finance/(tabs)/home/index.tsx b/code/app/app-rn4/src/app/finance/(tabs)/home/index.tsx
index dfcbb7b5..f4f606a1 100644
--- a/code/app/app-rn4/src/app/finance/(tabs)/home/index.tsx
+++ b/code/app/app-rn4/src/app/finance/(tabs)/home/index.tsx
@@ -7,18 +7,6 @@ import { loadDataApi } from "@/request/api";
export default function Home() {
const [dataList, setDataList] = useState([]);
- useEffect(() => {
- loadDataApi({
- view_name: "v_finance_record",
- search_condition: "",
- search_columns: [],
- order_by: "",
- args: [],
- }).then((res) => {
- console.log(res);
- });
- }, []);
-
return (
diff --git a/code/app/app-rn4/src/app/finance/add/index.tsx b/code/app/app-rn4/src/app/finance/add/index.tsx
new file mode 100644
index 00000000..be4a1e65
--- /dev/null
+++ b/code/app/app-rn4/src/app/finance/add/index.tsx
@@ -0,0 +1,241 @@
+import { View, Text, TouchableOpacity } from "react-native";
+import { Stack } from "expo-router";
+import PageLayout from "@/layouts/PageLayout";
+import { useState, useEffect, useRef } from "react";
+import LayoutView from "@/components/layout/view";
+import { ScrollShadow, Tabs, TextField, Label, Button, Input, BottomSheet } from "heroui-native";
+import { useFinanceStore } from "@/store/finance";
+import IconFont from "@/components/iconfont";
+import { LegendList } from "@legendapp/list";
+import { LinearGradient } from "expo-linear-gradient";
+import { ChevronRight } from "lucide-react-native";
+import { getCurrentDate } from "@/utils/time";
+import DateTime from "@/components/DateTime";
+
+export default function Add() {
+ const { getIncomeCategories, getExpenseCategories } = useFinanceStore((state) => state);
+
+ const [activeTab, setActiveTab] = useState("0");
+ const [categories, setCategories] = useState([]);
+ const [showMoreCategories, setShowMoreCategories] = useState(false);
+
+ const listRef = useRef(null);
+ const [selectedCategoryId, setSelectedCategoryId] = useState(null);
+
+ const [showRecordTime, setShowRecordTime] = useState(false);
+
+ const [form, setForm] = useState({
+ id: 0,
+ amount: "",
+ record_time: getCurrentDate(),
+ });
+
+ useEffect(() => {
+ const newCategories = activeTab === "0" ? getExpenseCategories() : getIncomeCategories();
+
+ setCategories(newCategories);
+ }, [activeTab]);
+
+ useEffect(() => {
+ if (!selectedCategoryId) {
+ listRef.current?.scrollToOffset?.({
+ offset: 0,
+ animated: false,
+ });
+ return;
+ }
+
+ const item = categories.find((c) => c.id === selectedCategoryId);
+
+ if (!item) {
+ listRef.current?.scrollToOffset?.({
+ offset: 0,
+ animated: false,
+ });
+ return;
+ }
+
+ requestAnimationFrame(() => {
+ listRef.current?.scrollToItem?.({
+ item,
+ animated: true,
+ viewPosition: 0.5,
+ });
+ });
+ }, [selectedCategoryId, categories]);
+
+ return (
+
+
+
+
+
+
+
+
+
+ 支出
+
+
+ 收入
+
+
+
+
+ {/*
+
+ */}
+
+
+
+ {
+ setShowMoreCategories(true);
+ }}
+ >
+ 更多
+
+
+
+
+ item.id.toString()}
+ extraData={selectedCategoryId}
+ renderItem={({ item }) => {
+ const isActive = selectedCategoryId === item.id;
+
+ return (
+ {
+ setSelectedCategoryId(item.id);
+ }}
+ className="items-center justify-center mr-3"
+ >
+
+
+
+
+
+ {item.name}
+
+
+ );
+ }}
+ showsHorizontalScrollIndicator={false}
+ className="flex-1"
+ />
+
+
+
+
+ {
+ setForm((prev: any) => ({
+ ...prev,
+ amount: value,
+ }));
+ }}
+ />
+
+
+
+
+ {
+ console.log("open date picker");
+ setShowRecordTime(true);
+ }}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ setForm((prev: any) => ({
+ ...prev,
+ record_time: value,
+ }));
+ setShowRecordTime(false);
+ }}
+ onClose={() => {
+ setShowRecordTime(false);
+ }}
+ />
+
+
+
+
+
+
+ {categories.map((item) => {
+ const isActive = selectedCategoryId === item.id;
+
+ return (
+ {
+ setSelectedCategoryId(item.id);
+
+ setShowMoreCategories(false);
+ }}
+ className="items-center justify-center w-1/4 mb-4"
+ >
+
+
+
+
+
+ {item.name}
+
+
+ );
+ })}
+
+
+
+
+
+ );
+}
diff --git a/code/app/app-rn4/src/app/index.tsx b/code/app/app-rn4/src/app/index.tsx
index 8eb619fa..3911d2b9 100644
--- a/code/app/app-rn4/src/app/index.tsx
+++ b/code/app/app-rn4/src/app/index.tsx
@@ -9,17 +9,35 @@ export default function Index() {
const router = useRouter();
useEffect(() => {
+ let isMounted = true;
+
const run = async () => {
- const { isLogged, userInfo } = useUserStore.getState();
- const familyStore = useFamilyStore.getState();
-
- if (!isLogged()) {
- router.replace("/auth/login");
- await SplashScreen.hideAsync();
- return;
- }
-
try {
+ const { isLogged, userInfo } = useUserStore.getState();
+ const familyStore = useFamilyStore.getState();
+
+ // 1️⃣ 未登录
+ if (!isLogged()) {
+ router.replace("/auth/login");
+ return;
+ }
+
+ // 2️⃣ 校验用户
+ const checkRes = await loadDataApi({
+ view_name: "b_user",
+ search_condition: "id = ?",
+ search_columns: ["id"],
+ order_by: "",
+ args: [userInfo.id],
+ });
+
+ if (!checkRes.isSuccess || !checkRes.data || checkRes.data.length === 0) {
+ toast.error("账号不存在或已被禁用");
+ router.replace("/auth/login");
+ return;
+ }
+
+ // 3️⃣ 查询家庭
const res = await loadDataApi({
view_name: "b_family_member",
search_condition: "user_id = ?",
@@ -28,26 +46,39 @@ export default function Index() {
args: [userInfo.id],
});
- if (res.isSuccess && res.data.length === 0) {
- familyStore.clear();
- toast.warning("你还没有加入任何家庭,请先创建或加入一个家庭");
-
- router.replace("/family/entry");
- } else {
- familyStore.setCurrentFamily({
- family_id: res.data[0].family_id,
- });
-
- router.replace("/(tabs)/home");
+ if (!res.isSuccess) {
+ throw new Error("获取家庭信息失败");
}
- } catch (e) {
- console.log(e);
- }
- await SplashScreen.hideAsync();
+ // 4️⃣ 无家庭
+ if (res.data.length === 0) {
+ familyStore.clear();
+ toast.warning("请先创建或加入家庭");
+ router.replace("/family/entry");
+ return;
+ }
+
+ // 5️⃣ 正常进入
+ familyStore.setCurrentFamily({
+ family_id: res.data[0].family_id,
+ });
+
+ router.replace("/(tabs)/home");
+ } catch (e) {
+ console.error(e);
+ toast.error("初始化失败,请稍后重试");
+ } finally {
+ if (isMounted) {
+ await SplashScreen.hideAsync();
+ }
+ }
};
run();
+
+ return () => {
+ isMounted = false;
+ };
}, []);
return null;
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceCanyin.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceCanyin.tsx
new file mode 100644
index 00000000..d76bac24
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceCanyin.tsx
@@ -0,0 +1,108 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceCanyin: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceCanyin);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceChongwu.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceChongwu.tsx
new file mode 100644
index 00000000..275bdba9
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceChongwu.tsx
@@ -0,0 +1,88 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceChongwu: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceChongwu);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceGongzi.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceGongzi.tsx
new file mode 100644
index 00000000..bd7c5128
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceGongzi.tsx
@@ -0,0 +1,60 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceGongzi: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceGongzi);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceGouwu.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceGouwu.tsx
new file mode 100644
index 00000000..efea2fa6
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceGouwu.tsx
@@ -0,0 +1,80 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceGouwu: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceGouwu);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceJianzhi.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceJianzhi.tsx
new file mode 100644
index 00000000..410de4e6
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceJianzhi.tsx
@@ -0,0 +1,60 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceJianzhi: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceJianzhi);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceJiaotong.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceJiaotong.tsx
new file mode 100644
index 00000000..256aee2e
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceJiaotong.tsx
@@ -0,0 +1,88 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceJiaotong: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceJiaotong);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceLijin.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceLijin.tsx
new file mode 100644
index 00000000..a3f376cf
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceLijin.tsx
@@ -0,0 +1,44 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceLijin: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceLijin);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceLingshi.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceLingshi.tsx
new file mode 100644
index 00000000..10b9834b
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceLingshi.tsx
@@ -0,0 +1,88 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceLingshi: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceLingshi);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceShicai.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceShicai.tsx
new file mode 100644
index 00000000..79fb1138
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceShicai.tsx
@@ -0,0 +1,92 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceShicai: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceShicai);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceShouru.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceShouru.tsx
new file mode 100644
index 00000000..1babda16
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceShouru.tsx
@@ -0,0 +1,44 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceShouru: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceShouru);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceShuidian.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceShuidian.tsx
new file mode 100644
index 00000000..88bb746b
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceShuidian.tsx
@@ -0,0 +1,44 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceShuidian: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceShuidian);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceShuma.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceShuma.tsx
new file mode 100644
index 00000000..3c7fdd70
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceShuma.tsx
@@ -0,0 +1,72 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceShuma: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceShuma);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceYifu.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceYifu.tsx
new file mode 100644
index 00000000..ba6dc7f6
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceYifu.tsx
@@ -0,0 +1,76 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceYifu: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceYifu);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceYiliao.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceYiliao.tsx
new file mode 100644
index 00000000..354e55f0
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceYiliao.tsx
@@ -0,0 +1,96 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceYiliao: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceYiliao);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceYouxi.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceYouxi.tsx
new file mode 100644
index 00000000..c2fd1dfe
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceYouxi.tsx
@@ -0,0 +1,564 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceYouxi: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceYouxi);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceYule.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceYule.tsx
new file mode 100644
index 00000000..8a5d3c79
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceYule.tsx
@@ -0,0 +1,68 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceYule: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceYule);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceYundong.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceYundong.tsx
new file mode 100644
index 00000000..3ffc0b86
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceYundong.tsx
@@ -0,0 +1,52 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceYundong: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceYundong);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceZhichu.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceZhichu.tsx
new file mode 100644
index 00000000..804208fa
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceZhichu.tsx
@@ -0,0 +1,44 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceZhichu: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceZhichu);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/IconFinanceZhufang.tsx b/code/app/app-rn4/src/components/iconfont/IconFinanceZhufang.tsx
new file mode 100644
index 00000000..9f3658e5
--- /dev/null
+++ b/code/app/app-rn4/src/components/iconfont/IconFinanceZhufang.tsx
@@ -0,0 +1,48 @@
+/* eslint-disable */
+/* tslint:disable */
+
+import React from 'react';
+import type { FunctionComponent } from 'react';
+import type { ViewProps } from 'react-native';
+import { Svg, GProps, Path } from 'react-native-svg';
+import { getIconColor } from './helper';
+
+interface Props extends Omit, ViewProps {
+ size?: number;
+ color?: string | string[];
+}
+
+const IconFinanceZhufang: FunctionComponent = ({
+ size = 18,
+ color,
+ ...rest
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default React.memo(IconFinanceZhufang);
\ No newline at end of file
diff --git a/code/app/app-rn4/src/components/iconfont/index.tsx b/code/app/app-rn4/src/components/iconfont/index.tsx
index 452d86c9..f990ae07 100644
--- a/code/app/app-rn4/src/components/iconfont/index.tsx
+++ b/code/app/app-rn4/src/components/iconfont/index.tsx
@@ -4,16 +4,54 @@
import React, { FunctionComponent } from 'react';
import { ViewProps } from 'react-native';
import { GProps } from 'react-native-svg';
+import IconFinanceYifu from './IconFinanceYifu';
+import IconFinanceJianzhi from './IconFinanceJianzhi';
+import IconFinanceLijin from './IconFinanceLijin';
+import IconFinanceGongzi from './IconFinanceGongzi';
+import IconFinanceChongwu from './IconFinanceChongwu';
+import IconFinanceShouru from './IconFinanceShouru';
+import IconFinanceZhufang from './IconFinanceZhufang';
+import IconFinanceShuidian from './IconFinanceShuidian';
+import IconFinanceZhichu from './IconFinanceZhichu';
+import IconFinanceYule from './IconFinanceYule';
+import IconFinanceYundong from './IconFinanceYundong';
+import IconFinanceYouxi from './IconFinanceYouxi';
+import IconFinanceGouwu from './IconFinanceGouwu';
+import IconFinanceLingshi from './IconFinanceLingshi';
+import IconFinanceYiliao from './IconFinanceYiliao';
+import IconFinanceShuma from './IconFinanceShuma';
+import IconFinanceCanyin from './IconFinanceCanyin';
+import IconFinanceJiaotong from './IconFinanceJiaotong';
+import IconFinanceShicai from './IconFinanceShicai';
import IconAppFinance from './IconAppFinance';
import IconAppClothes from './IconAppClothes';
import IconWeixin from './IconWeixin';
import IconQq from './IconQq';
+export { default as IconFinanceYifu } from './IconFinanceYifu';
+export { default as IconFinanceJianzhi } from './IconFinanceJianzhi';
+export { default as IconFinanceLijin } from './IconFinanceLijin';
+export { default as IconFinanceGongzi } from './IconFinanceGongzi';
+export { default as IconFinanceChongwu } from './IconFinanceChongwu';
+export { default as IconFinanceShouru } from './IconFinanceShouru';
+export { default as IconFinanceZhufang } from './IconFinanceZhufang';
+export { default as IconFinanceShuidian } from './IconFinanceShuidian';
+export { default as IconFinanceZhichu } from './IconFinanceZhichu';
+export { default as IconFinanceYule } from './IconFinanceYule';
+export { default as IconFinanceYundong } from './IconFinanceYundong';
+export { default as IconFinanceYouxi } from './IconFinanceYouxi';
+export { default as IconFinanceGouwu } from './IconFinanceGouwu';
+export { default as IconFinanceLingshi } from './IconFinanceLingshi';
+export { default as IconFinanceYiliao } from './IconFinanceYiliao';
+export { default as IconFinanceShuma } from './IconFinanceShuma';
+export { default as IconFinanceCanyin } from './IconFinanceCanyin';
+export { default as IconFinanceJiaotong } from './IconFinanceJiaotong';
+export { default as IconFinanceShicai } from './IconFinanceShicai';
export { default as IconAppFinance } from './IconAppFinance';
export { default as IconAppClothes } from './IconAppClothes';
export { default as IconWeixin } from './IconWeixin';
export { default as IconQq } from './IconQq';
-export type IconNames = 'app_finance' | 'app_clothes' | 'weixin' | 'QQ';
+export type IconNames = 'finance_yifu' | 'finance_jianzhi' | 'finance_lijin' | 'finance_gongzi' | 'finance_chongwu' | 'finance_shouru' | 'finance_zhufang' | 'finance_shuidian' | 'finance_zhichu' | 'finance_yule' | 'finance_yundong' | 'finance_youxi' | 'finance_gouwu' | 'finance_lingshi' | 'finance_yiliao' | 'finance_shuma' | 'finance_canyin' | 'finance_jiaotong' | 'finance_shicai' | 'app_finance' | 'app_clothes' | 'weixin' | 'QQ';
interface Props extends GProps, ViewProps {
name: IconNames;
@@ -23,14 +61,52 @@ interface Props extends GProps, ViewProps {
let IconFont: FunctionComponent = ({ name, ...rest }) => {
switch (name) {
+ case 'finance_yifu':
+ return ;
+ case 'finance_jianzhi':
+ return ;
+ case 'finance_lijin':
+ return ;
+ case 'finance_gongzi':
+ return ;
+ case 'finance_chongwu':
+ return ;
+ case 'finance_shouru':
+ return ;
+ case 'finance_zhufang':
+ return ;
+ case 'finance_shuidian':
+ return ;
+ case 'finance_zhichu':
+ return ;
+ case 'finance_yule':
+ return ;
+ case 'finance_yundong':
+ return ;
+ case 'finance_youxi':
+ return ;
+ case 'finance_gouwu':
+ return ;
+ case 'finance_lingshi':
+ return ;
+ case 'finance_yiliao':
+ return ;
+ case 'finance_shuma':
+ return ;
+ case 'finance_canyin':
+ return ;
+ case 'finance_jiaotong':
+ return ;
+ case 'finance_shicai':
+ return ;
case 'app_finance':
- return ;
+ return ;
case 'app_clothes':
- return ;
+ return ;
case 'weixin':
- return ;
+ return ;
case 'QQ':
- return ;
+ return ;
}
return null;
diff --git a/code/app/app-rn4/src/components/layout/navbar.tsx b/code/app/app-rn4/src/components/layout/navbar.tsx
index 84c7701e..e58fbc80 100644
--- a/code/app/app-rn4/src/components/layout/navbar.tsx
+++ b/code/app/app-rn4/src/components/layout/navbar.tsx
@@ -4,10 +4,12 @@ import { cn } from "@/utils/cn";
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from "react-native-reanimated";
import { Shadow } from "react-native-shadow-2";
import { ChevronLeft, SlidersHorizontal, CirclePower, LucideIcon } from "lucide-react-native";
+import { ReactNode } from "react";
interface NavbarProps {
title?: string;
titleIcon?: LucideIcon;
+ renderTitle?: () => ReactNode;
showBack?: boolean;
onBack?: () => void;
@@ -23,6 +25,7 @@ const AnimatedView = Animated.View;
export default function Navbar({
title,
titleIcon,
+ renderTitle,
showBack = true,
onBack,
onClose,
@@ -87,48 +90,31 @@ export default function Navbar({
)}
- {title && (
-
- {TitleIcon && }
-
- {title}
-
-
+ {(renderTitle || title) && (
+
+ {renderTitle ? (
+ renderTitle()
+ ) : (
+ <>
+ {TitleIcon && }
+
+ {title}
+
+ >
+ )}
+
)}
-
-
+
{
leftScale.value = withSpring(0.8);
@@ -143,7 +129,7 @@ export default function Navbar({
-
+
{
@@ -157,7 +143,7 @@ export default function Navbar({
-
+
);
}
diff --git a/code/app/app-rn4/src/components/layout/tabbar.tsx b/code/app/app-rn4/src/components/layout/tabbar.tsx
index aeb6fb11..9023d670 100644
--- a/code/app/app-rn4/src/components/layout/tabbar.tsx
+++ b/code/app/app-rn4/src/components/layout/tabbar.tsx
@@ -1,7 +1,6 @@
import { View, StyleProp, ViewStyle, Pressable, StyleSheet } from "react-native";
import { LucideIcon } from "lucide-react-native";
import { cn } from "@/utils/cn";
-import { Shadow } from "react-native-shadow-2";
import Animated, { useSharedValue, useAnimatedStyle, withTiming } from "react-native-reanimated";
export interface TabbarItem {
@@ -29,12 +28,7 @@ export default function Tabbar({ tabs, value, onChange, className, style }: Tabb
return (
-
+
{tabs.map((tab) =>
tab.isCenter ? (
@@ -49,7 +43,7 @@ export default function Tabbar({ tabs, value, onChange, className, style }: Tabb
),
)}
-
+
);
}
@@ -125,7 +119,7 @@ function CenterButton({ tab, onPress }: { tab: TabbarItem; onPress?: () => void
}}
>
- {/* void
borderColor: "white",
top: -4,
}}
- > */}
-
+ {/*
+ > */}
-
- {/* */}
+ {/* */}
+
diff --git a/code/app/app-rn4/src/components/layout/view.tsx b/code/app/app-rn4/src/components/layout/view.tsx
index 5f67322d..38140aa1 100644
--- a/code/app/app-rn4/src/components/layout/view.tsx
+++ b/code/app/app-rn4/src/components/layout/view.tsx
@@ -1,6 +1,5 @@
import React, { forwardRef } from "react";
import {
- ScrollView,
SectionList,
FlatList,
View,
@@ -8,6 +7,7 @@ import {
StyleProp,
ViewStyle,
} from "react-native";
+import { KeyboardAwareScrollView } from "react-native-keyboard-controller";
import { ScrollShadow } from "heroui-native";
import { LinearGradient } from "expo-linear-gradient";
@@ -65,15 +65,18 @@ const LayoutView = ({ className, style, children, ...rest }: LayoutViewProps) =>
/* ========================= ScrollView ========================= */
LayoutView.ScrollView = forwardRef<
- ScrollView,
- React.ComponentProps & LayoutConfig
+ any,
+ React.ComponentProps & LayoutConfig
>(({ topExtraPadding, bottomExtraPadding, contentContainerStyle, ...props }, ref) => {
- const padding = useContentPadding({ topExtraPadding, bottomExtraPadding });
+ const padding = useContentPadding({
+ topExtraPadding,
+ bottomExtraPadding,
+ });
return (
-
);
-});
+}) as any;
/* ========================= SectionList ========================= */
diff --git a/code/app/app-rn4/src/layouts/PageLayout.tsx b/code/app/app-rn4/src/layouts/PageLayout.tsx
index fa3b84f7..8388fe54 100644
--- a/code/app/app-rn4/src/layouts/PageLayout.tsx
+++ b/code/app/app-rn4/src/layouts/PageLayout.tsx
@@ -1,16 +1,18 @@
-import React from "react";
import { View } from "react-native";
import { Slot, useRouter } from "expo-router";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import Navbar from "@/components/layout/navbar";
+import { ReactNode } from "react";
interface ModuleLayoutProps {
title?: string;
titleIcon?: any;
- children?: React.ReactNode;
+ children?: ReactNode;
+
+ renderTitle?: () => ReactNode;
}
-export default function PageLayout({ title, titleIcon, children }: ModuleLayoutProps) {
+export default function PageLayout({ title, titleIcon, children, renderTitle }: ModuleLayoutProps) {
const router = useRouter();
const insets = useSafeAreaInsets();
@@ -39,6 +41,7 @@ export default function PageLayout({ title, titleIcon, children }: ModuleLayoutP
void;
+ clearCategories: () => void;
+
+ getCategories: () => any[];
+ getExpenseCategories: () => any[];
+ getIncomeCategories: () => any[];
+}
+
+export const useFinanceStore = create((set, get) => ({
+ categories: [],
+ setCategories: (categories: any[]) => set({ categories }),
+ clearCategories: () => set({ categories: [] }),
+
+ getCategories: () => get().categories,
+ getExpenseCategories: () => get().categories.filter((category) => category.type === 0),
+ getIncomeCategories: () => get().categories.filter((category) => category.type === 1),
+}));
diff --git a/code/app/app-rn4/src/store/index.ts b/code/app/app-rn4/src/store/index.ts
index c6884be2..0eca216c 100644
--- a/code/app/app-rn4/src/store/index.ts
+++ b/code/app/app-rn4/src/store/index.ts
@@ -1,4 +1,4 @@
export * from "./app";
export * from "./user";
-export * from "./space";
+export * from "./finance";
export * from "./family";
diff --git a/code/app/app-rn4/src/store/space.ts b/code/app/app-rn4/src/store/space.ts
deleted file mode 100644
index 3659b9b3..00000000
--- a/code/app/app-rn4/src/store/space.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { create } from "zustand";
-
-interface Space {
- space_id: number;
-}
-
-interface SpaceState {
- currentSpace: Space | null;
- setCurrentSpace: (space: Space | null) => void;
- clear: () => void;
- inSpace: () => boolean;
-}
-
-export const useSpaceStore = create((set, get) => ({
- currentSpace: null,
-
- setCurrentSpace: (space) =>
- set({
- currentSpace: space,
- }),
-
- clear: () =>
- set({
- currentSpace: null,
- }),
-
- inSpace: () => {
- const currentSpace = get().currentSpace;
- return currentSpace !== null && currentSpace.space_id !== 0;
- },
-}));