Files
money.sori.studio/composables/useTransactionFavorites.ts

75 lines
1.9 KiB
TypeScript

type FavoriteTransactionInput = {
type: 'income' | 'expense'
assetId: string
categoryId: string
amount: number
title: string
memo?: string
latitude?: number | null
longitude?: number | null
}
export type FavoriteTransaction = FavoriteTransactionInput & {
id: string
savedAt: string
}
const storageKey = 'money_favorite_transactions'
function readFavorites() {
if (!import.meta.client) return []
try {
const parsed = JSON.parse(localStorage.getItem(storageKey) || '[]')
return Array.isArray(parsed) ? parsed as FavoriteTransaction[] : []
} catch {
return []
}
}
function writeFavorites(items: FavoriteTransaction[]) {
if (!import.meta.client) return
localStorage.setItem(storageKey, JSON.stringify(items.slice(0, 20)))
}
export function useTransactionFavorites() {
const favorites = useState<FavoriteTransaction[]>('transactionFavorites', () => [])
function loadFavorites() {
favorites.value = readFavorites()
}
function saveFavorite(input: FavoriteTransactionInput) {
const title = input.title.trim()
if (!title || !input.assetId || !input.categoryId || !input.amount) return null
const items = readFavorites().filter(item => !(
item.type === input.type &&
item.assetId === input.assetId &&
item.categoryId === input.categoryId &&
item.amount === input.amount &&
item.title === title
))
const favorite: FavoriteTransaction = {
...input,
title,
memo: input.memo?.trim().slice(0, 60) || '',
id: globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(36).slice(2)}`,
savedAt: new Date().toISOString()
}
writeFavorites([favorite, ...items])
loadFavorites()
return favorite
}
function removeFavorite(id: string) {
writeFavorites(readFavorites().filter(item => item.id !== id))
loadFavorites()
}
return {
favorites,
loadFavorites,
saveFavorite,
removeFavorite
}
}