feat: add account management types and zustand store implementation
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
"@tauri-apps/plugin-opener": "^2",
|
"@tauri-apps/plugin-opener": "^2",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"isbot": "^5",
|
||||||
"lucide-react": "^1.16.0",
|
"lucide-react": "^1.16.0",
|
||||||
"radix-ui": "^1.4.3",
|
"radix-ui": "^1.4.3",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
@@ -33,7 +34,8 @@
|
|||||||
"tailwind-merge": "^3.6.0",
|
"tailwind-merge": "^3.6.0",
|
||||||
"tailwindcss": "^4.3.0",
|
"tailwindcss": "^4.3.0",
|
||||||
"tw-animate-css": "^1.4.0",
|
"tw-animate-css": "^1.4.0",
|
||||||
"isbot": "^5"
|
"vaul": "^1.1.2",
|
||||||
|
"zustand": "^5.0.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-router/dev": "^7.15.1",
|
"@react-router/dev": "^7.15.1",
|
||||||
|
|||||||
45
pnpm-lock.yaml
generated
45
pnpm-lock.yaml
generated
@@ -62,6 +62,12 @@ importers:
|
|||||||
tw-animate-css:
|
tw-animate-css:
|
||||||
specifier: ^1.4.0
|
specifier: ^1.4.0
|
||||||
version: 1.4.0
|
version: 1.4.0
|
||||||
|
vaul:
|
||||||
|
specifier: ^1.1.2
|
||||||
|
version: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||||
|
zustand:
|
||||||
|
specifier: ^5.0.13
|
||||||
|
version: 5.0.13(@types/react@19.2.15)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6))
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@react-router/dev':
|
'@react-router/dev':
|
||||||
specifier: ^7.15.1
|
specifier: ^7.15.1
|
||||||
@@ -3185,6 +3191,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
|
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
|
vaul@1.1.2:
|
||||||
|
resolution: {integrity: sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc
|
||||||
|
|
||||||
vite-node@3.2.4:
|
vite-node@3.2.4:
|
||||||
resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==}
|
resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==}
|
||||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||||
@@ -3286,6 +3298,24 @@ packages:
|
|||||||
zod@3.25.76:
|
zod@3.25.76:
|
||||||
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
|
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
|
||||||
|
|
||||||
|
zustand@5.0.13:
|
||||||
|
resolution: {integrity: sha512-efI2tVaVQPqtOh114loML/Z80Y4NP3yc+Ff0fYiZJPauNeWZeIp/bRFD7I9bfmCOYBh/PHxlglQ9+wvlwnPikQ==}
|
||||||
|
engines: {node: '>=12.20.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '>=18.0.0'
|
||||||
|
immer: '>=9.0.6'
|
||||||
|
react: '>=18.0.0'
|
||||||
|
use-sync-external-store: '>=1.2.0'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
immer:
|
||||||
|
optional: true
|
||||||
|
react:
|
||||||
|
optional: true
|
||||||
|
use-sync-external-store:
|
||||||
|
optional: true
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@babel/code-frame@7.29.7':
|
'@babel/code-frame@7.29.7':
|
||||||
@@ -6377,6 +6407,15 @@ snapshots:
|
|||||||
|
|
||||||
vary@1.1.2: {}
|
vary@1.1.2: {}
|
||||||
|
|
||||||
|
vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||||
|
react: 19.2.6
|
||||||
|
react-dom: 19.2.6(react@19.2.6)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/react'
|
||||||
|
- '@types/react-dom'
|
||||||
|
|
||||||
vite-node@3.2.4(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0):
|
vite-node@3.2.4(@types/node@25.9.1)(jiti@2.7.0)(lightningcss@1.32.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
cac: 6.7.14
|
cac: 6.7.14
|
||||||
@@ -6462,3 +6501,9 @@ snapshots:
|
|||||||
zod: 3.25.76
|
zod: 3.25.76
|
||||||
|
|
||||||
zod@3.25.76: {}
|
zod@3.25.76: {}
|
||||||
|
|
||||||
|
zustand@5.0.13(@types/react@19.2.15)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)):
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 19.2.15
|
||||||
|
react: 19.2.6
|
||||||
|
use-sync-external-store: 1.6.0(react@19.2.6)
|
||||||
|
|||||||
11
src/lib/tauri/types/account.ts
Normal file
11
src/lib/tauri/types/account.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export type AccountType = 'Asset' | 'Liability' | 'Unknown';
|
||||||
|
export type Account = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
accountType: AccountType;
|
||||||
|
balance: string;
|
||||||
|
accountCategory: string;
|
||||||
|
//
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
};
|
||||||
50
src/store/accounts.ts
Normal file
50
src/store/accounts.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { StateCreator } from 'zustand';
|
||||||
|
import { Account as TauriAccount } from '../lib/tauri/types/account';
|
||||||
|
|
||||||
|
export type Account = TauriAccount;
|
||||||
|
|
||||||
|
export interface AccountsSlice {
|
||||||
|
accounts: Account[];
|
||||||
|
selectedAccountId?: string;
|
||||||
|
//
|
||||||
|
selectAccount: (accountId: string) => void;
|
||||||
|
addAccount: (account: Account) => void;
|
||||||
|
removeAccount: (accountId: string) => void;
|
||||||
|
updateAccount: (account: Account) => void;
|
||||||
|
reloadAccounts: (accounts?: Account[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createAccountsSlice: StateCreator<AccountsSlice, [], [], AccountsSlice> = (set) => ({
|
||||||
|
accounts: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
name: 'Checking Account',
|
||||||
|
accountType: 'Asset',
|
||||||
|
balance: '5000.00',
|
||||||
|
accountCategory: 'Bank',
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
selectedAccountId: '1',
|
||||||
|
selectAccount: (accountId) =>
|
||||||
|
set(() => {
|
||||||
|
return { selectedAccountId: accountId };
|
||||||
|
}),
|
||||||
|
addAccount: (account) =>
|
||||||
|
set((state) => {
|
||||||
|
return { accounts: [...state.accounts, account] };
|
||||||
|
}),
|
||||||
|
removeAccount: (accountId) =>
|
||||||
|
set((state) => {
|
||||||
|
return { accounts: state.accounts.filter((account) => account.id !== accountId) };
|
||||||
|
}),
|
||||||
|
updateAccount: (updatedAccount) =>
|
||||||
|
set((state) => {
|
||||||
|
return { accounts: state.accounts.map((account) => (account.id === updatedAccount.id ? updatedAccount : account)) };
|
||||||
|
}),
|
||||||
|
reloadAccounts: (accounts?: Account[]) =>
|
||||||
|
set((_state) => {
|
||||||
|
return { accounts: accounts ?? [] };
|
||||||
|
}),
|
||||||
|
});
|
||||||
8
src/store/index.ts
Normal file
8
src/store/index.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { create } from 'zustand';
|
||||||
|
import { type AccountsSlice, createAccountsSlice } from './accounts';
|
||||||
|
|
||||||
|
export interface AppStore extends AccountsSlice {}
|
||||||
|
|
||||||
|
export const useAppStore = create<AppStore>()((...a) => ({
|
||||||
|
...createAccountsSlice(...a),
|
||||||
|
}));
|
||||||
Reference in New Issue
Block a user