mirror of
https://github.com/Lifeforge-app/lifeforge.git
synced 2026-06-28 14:55:45 +00:00
25w27
Former-commit-id: d9ad6a54db75ba160fd2fceb4fdcc107d785603c [formerly 10734618a783fab90e38202d95eb42bde6f570f6] [formerly db810a6126969e2598de30b207967ce42866d21b [formerly cde19d38d100d14e77744b8b37093eb1d45ee05a]] Former-commit-id: 0cd9223971314d2159e4c05ac7129a86b3088def [formerly e88a40fea5b7ccfbbbea5fafef25f53b4b2242fa] Former-commit-id: 2a40542295fd872a91c0a00431732b014c2aeb04
This commit is contained in:
@@ -5,10 +5,12 @@
|
||||
- **Books Library**: Renamed `category` to `collection` for better clarity.
|
||||
- **Books Library**: Fixed a bug where the sidebar content is not updated when stuff got deleted.
|
||||
- **Books Library**: Download process is now handled by the task pool mechanism.
|
||||
- **Books Library**: User can now download books from different mirrors of Libgen.
|
||||
- **Guitar Tabs**: Download process is now handled by the task pool mechanism.
|
||||
- **API**: Implemented task pool mechanism using socketIO to handle long-running tasks like downloading books from Libgen.
|
||||
- **UI**: Added inline style for the `preloader` component so that styling will be applied when tailwind is not loaded yet.
|
||||
- **UI**: Completely revamped the `ModalStore`, now you can pass in the modal component directly into the `open` function instead of registering it first. This allow facilitate the type safety of the modal component.
|
||||
- **UI**: Fixed a bug in combobox input where the input will not be focused when the user click the area outside of the input itself in the container.
|
||||
|
||||
## 📌 **dev 25w26 (6/23/2025 - 6/30/2025)**
|
||||
- **Movies**: Added tab selector to separate watched and unwatched movies.
|
||||
|
||||
6
bun.lock
6
bun.lock
@@ -8,7 +8,7 @@
|
||||
"@headlessui/react": "^2.2.2",
|
||||
"@iconify/react": "^5.2.1",
|
||||
"@iconify/types": "^2.0.0",
|
||||
"@lifeforge/ui": "^0.25.27-4",
|
||||
"@lifeforge/ui": "^0.25.27-8",
|
||||
"@million/lint": "^1.0.14",
|
||||
"@tabler/icons-react": "^3.31.0",
|
||||
"@tailwindcss/postcss": "^4.1.5",
|
||||
@@ -17,7 +17,7 @@
|
||||
"@tanstack/react-query-devtools": "^5.75.1",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"@uiw/react-color": "^2.5.3",
|
||||
"@vis.gl/react-google-maps": "^1.5.2",
|
||||
"@vis.gl/react-google-maps": "^1.5.3",
|
||||
"@wavesurfer/react": "^1.0.11",
|
||||
"babel-plugin-react-compiler": "^19.0.0-beta-ebf51a3-20250411",
|
||||
"chart.js": "^4.4.9",
|
||||
@@ -300,7 +300,7 @@
|
||||
|
||||
"@kurkle/color": ["@kurkle/color@0.3.4", "", {}, "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w=="],
|
||||
|
||||
"@lifeforge/ui": ["@lifeforge/ui@0.25.27-4", "", { "dependencies": { "@headlessui/react": "^2.2.2", "@iconify/collections": "^1.0.544", "@iconify/react": "^5.2.1", "@million/lint": "^1.0.14", "@tailwindcss/typography": "^0.5.16", "@tanstack/react-query": "^5.75.4", "@uidotdev/usehooks": "^2.4.1", "@uiw/react-color": "^2.5.3", "@vitejs/plugin-react": "^4.4.1", "@yudiel/react-qr-scanner": "^2.3.0", "clsx": "^2.1.1", "color-sorter": "^6.2.0", "crypto-js": "^4.2.0", "daisyui": "^5.0.37", "dayjs": "^1.11.13", "file-type-mime": "^0.4.6", "i18next-http-backend": "^3.0.2", "javascript-color-gradient": "^2.5.0", "lodash": "^4.17.21", "pocketbase": "^0.25.2", "radix-ui": "^1.3.4", "react-currency-input-field": "^3.10.0", "react-custom-scrollbars": "^4.2.1", "react-date-picker": "^11.0.0", "react-datepicker": "^8.4.0", "react-datetime-picker": "^6.0.1", "react-dropzone": "^14.3.8", "react-i18next": "^15.5.1", "react-medium-image-zoom": "^5.2.14", "react-otp-input": "^3.1.1", "react-photo-album": "^2.4.1", "react-router": "^7.5.3", "react-toastify": "^10.0.6", "react-tooltip": "^5.28.1", "react-virtualized": "^9.22.6", "tailwindcss": "^4.1.5", "tinycolor2": "^1.6.0", "zustand": "^5.0.4" }, "peerDependencies": { "react": "^19.0.0", "react-dom": "^19.0.0" } }, "sha512-zGjwOvLPBcviQ/cDruPaJb+F1Mhj6m9NkPNCVt4R/lxmCLrhz46EZD6kE9Er6SToTQcuyk2AooBhtSk1SKgEKw=="],
|
||||
"@lifeforge/ui": ["@lifeforge/ui@0.25.27-8", "", { "dependencies": { "@headlessui/react": "^2.2.2", "@iconify/collections": "^1.0.544", "@iconify/react": "^5.2.1", "@million/lint": "^1.0.14", "@tailwindcss/typography": "^0.5.16", "@tanstack/react-query": "^5.75.4", "@uidotdev/usehooks": "^2.4.1", "@uiw/react-color": "^2.5.3", "@vitejs/plugin-react": "^4.4.1", "@yudiel/react-qr-scanner": "^2.3.0", "clsx": "^2.1.1", "color-sorter": "^6.2.0", "crypto-js": "^4.2.0", "daisyui": "^5.0.37", "dayjs": "^1.11.13", "file-type-mime": "^0.4.6", "i18next-http-backend": "^3.0.2", "javascript-color-gradient": "^2.5.0", "lodash": "^4.17.21", "pocketbase": "^0.25.2", "radix-ui": "^1.3.4", "react-currency-input-field": "^3.10.0", "react-custom-scrollbars": "^4.2.1", "react-date-picker": "^11.0.0", "react-datepicker": "^8.4.0", "react-datetime-picker": "^6.0.1", "react-dropzone": "^14.3.8", "react-i18next": "^15.5.1", "react-medium-image-zoom": "^5.2.14", "react-otp-input": "^3.1.1", "react-photo-album": "^2.4.1", "react-router": "^7.5.3", "react-toastify": "^10.0.6", "react-tooltip": "^5.28.1", "react-virtualized": "^9.22.6", "tailwindcss": "^4.1.5", "tinycolor2": "^1.6.0", "zustand": "^5.0.4" }, "peerDependencies": { "react": "^19.0.0", "react-dom": "^19.0.0" } }, "sha512-ZG9Djqp9aN6aGqrXUp04lKb5KOMI6BpIijdLQpHK+aN800chF+HGlxdX581HT2WpzhrFOUFAG3oOZ44ImeTZfA=="],
|
||||
|
||||
"@million/install": ["@million/install@1.0.14", "", { "dependencies": { "@antfu/ni": "^0.21.12", "@axiomhq/js": "1.0.0-rc.3", "@babel/parser": "^7.25.3", "@babel/types": "7.26.0", "@clack/prompts": "^0.7.0", "ast-types": "^0.14.2", "cli-high": "^0.4.2", "diff": "^5.1.0", "effect": "^3.8.4", "nanoid": "^5.0.7", "recast": "^0.23.9", "xycolors": "^0.1.2" }, "bin": { "install": "bin/index.js" } }, "sha512-xZvj4AEHc5hyn8RCiLl9dYNqggj2fa0lgNvUkCiJyhRJPNE2hZrUa/Ka0Weu82VpBaO//zujG0YErk7osjNXPA=="],
|
||||
|
||||
|
||||
3
env/.env.example
vendored
3
env/.env.example
vendored
@@ -1 +1,2 @@
|
||||
VITE_API_HOST=
|
||||
VITE_API_HOST=
|
||||
VITE_GOOGLE_MAPS_API_KEY=
|
||||
@@ -17,7 +17,7 @@
|
||||
"@headlessui/react": "^2.2.2",
|
||||
"@iconify/react": "^5.2.1",
|
||||
"@iconify/types": "^2.0.0",
|
||||
"@lifeforge/ui": "^0.25.27-4",
|
||||
"@lifeforge/ui": "^0.25.27-8",
|
||||
"@million/lint": "^1.0.14",
|
||||
"@tabler/icons-react": "^3.31.0",
|
||||
"@tailwindcss/postcss": "^4.1.5",
|
||||
@@ -26,7 +26,7 @@
|
||||
"@tanstack/react-query-devtools": "^5.75.1",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"@uiw/react-color": "^2.5.3",
|
||||
"@vis.gl/react-google-maps": "^1.5.2",
|
||||
"@vis.gl/react-google-maps": "^1.5.3",
|
||||
"@wavesurfer/react": "^1.0.11",
|
||||
"babel-plugin-react-compiler": "^19.0.0-beta-ebf51a3-20250411",
|
||||
"chart.js": "^4.4.9",
|
||||
|
||||
@@ -45,7 +45,7 @@ function ModifyEventModal({
|
||||
use_google_map: false,
|
||||
category: '',
|
||||
calendar: '',
|
||||
location: '',
|
||||
location: null,
|
||||
reference_link: '',
|
||||
description: '',
|
||||
recurring_rrule: '',
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { RecordModel } from 'pocketbase'
|
||||
|
||||
import { ILocationEntry } from '@lifeforge/ui'
|
||||
|
||||
interface ICalendarEvent extends RecordModel {
|
||||
type: 'single' | 'recurring'
|
||||
title: string
|
||||
@@ -24,7 +26,7 @@ type ICalendarEventFormState = {
|
||||
use_google_map: boolean
|
||||
category: string
|
||||
calendar: string
|
||||
location: string
|
||||
location: string | ILocationEntry | null
|
||||
reference_link: string
|
||||
description: string
|
||||
type: 'single' | 'recurring'
|
||||
|
||||
@@ -44,7 +44,11 @@ interface IWalletTransaction extends RecordModel {
|
||||
side: 'debit' | 'credit'
|
||||
particulars: string
|
||||
amount: number
|
||||
location: string
|
||||
location_name: string
|
||||
location_coords: {
|
||||
lat: number
|
||||
lon: number
|
||||
}
|
||||
date: string
|
||||
category: string
|
||||
asset: string
|
||||
|
||||
@@ -92,6 +92,7 @@ function AssetItem({ asset }: { asset: IWalletAsset }) {
|
||||
>
|
||||
<MenuItem
|
||||
icon="tabler:chart-line"
|
||||
namespace="apps.wallet"
|
||||
text="View Balance Chart"
|
||||
onClick={handleOpenBalanceChart}
|
||||
/>
|
||||
|
||||
@@ -137,7 +137,9 @@ function BalanceChartModal({
|
||||
return (
|
||||
<div className="min-w-[50vw]">
|
||||
<ModalHeader
|
||||
appendTitle={<> - {existedData.name}</>}
|
||||
appendTitle={
|
||||
<p className="hidden truncate sm:block"> - {existedData.name}</p>
|
||||
}
|
||||
icon="tabler:chart-line"
|
||||
namespace="apps.wallet"
|
||||
title="assetsBalanceChart"
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Button,
|
||||
CurrencyInput,
|
||||
DateInput,
|
||||
ILocationEntry,
|
||||
ImageAndFileInput,
|
||||
LocationInput,
|
||||
ModalHeader,
|
||||
@@ -43,7 +44,7 @@ function ModifyTransactionsModal({
|
||||
|
||||
const [transactionDate, setTransactionDate] = useState<Date | null>(null)
|
||||
const [amount, setAmount] = useState<string>()
|
||||
const [location, setLocation] = useState<string | null>(null)
|
||||
const [location, setLocation] = useState<ILocationEntry | null>(null)
|
||||
const [category, setCategory] = useState<string | null>(null)
|
||||
const [transactionAsset, setTransactionAsset] = useState<string | null>(null)
|
||||
const [ledger, setLedger] = useState<string | null>(null)
|
||||
@@ -80,7 +81,26 @@ function ModifyTransactionsModal({
|
||||
)
|
||||
setAmount(`${existedData.amount}`)
|
||||
setCategory(existedData.category || '')
|
||||
setLocation(existedData.location || '')
|
||||
setLocation(
|
||||
existedData.location_name
|
||||
? {
|
||||
displayName: {
|
||||
text: existedData.location_name,
|
||||
languageCode: ''
|
||||
},
|
||||
location: existedData.location_coords
|
||||
? {
|
||||
latitude: existedData.location_coords.lat,
|
||||
longitude: existedData.location_coords.lon
|
||||
}
|
||||
: {
|
||||
latitude: 0,
|
||||
longitude: 0
|
||||
},
|
||||
formattedAddress: ''
|
||||
}
|
||||
: null
|
||||
)
|
||||
setTransactionAsset(existedData.asset || '')
|
||||
setLedger(existedData.ledger || '')
|
||||
setReceipt(
|
||||
@@ -104,7 +124,7 @@ function ModifyTransactionsModal({
|
||||
setTransactionType('income')
|
||||
setTransactionDate(dayjs().toDate())
|
||||
setAmount(undefined)
|
||||
setLocation('')
|
||||
setLocation(null)
|
||||
setCategory(null)
|
||||
setTransactionAsset(null)
|
||||
setLedger(null)
|
||||
@@ -140,8 +160,8 @@ function ModifyTransactionsModal({
|
||||
data.append('date', dayjs(transactionDate).format('YYYY-MM-DD'))
|
||||
data.append('amount', parseFloat(`${amount}` || '0').toString())
|
||||
data.append('category', category ?? '')
|
||||
data.append('location', location ?? '')
|
||||
|
||||
data.append('location_name', location?.displayName.text ?? '')
|
||||
data.append('location_coords', JSON.stringify(location?.location))
|
||||
data.append('asset', transactionAsset ?? '')
|
||||
data.append('ledger', ledger ?? '')
|
||||
data.append('type', transactionType)
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
import { ModalHeader } from '@lifeforge/ui'
|
||||
import { Icon } from '@iconify/react/dist/iconify.js'
|
||||
import { APIProvider, AdvancedMarker, Map } from '@vis.gl/react-google-maps'
|
||||
import clsx from 'clsx'
|
||||
import dayjs from 'dayjs'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { Button, ModalHeader, useModalStore } from '@lifeforge/ui'
|
||||
|
||||
import { useWalletData } from '@apps/Wallet/hooks/useWalletData'
|
||||
import { IWalletTransaction } from '@apps/Wallet/interfaces/wallet_interfaces'
|
||||
|
||||
import useComponentBg from '@hooks/useComponentBg'
|
||||
|
||||
import ViewReceiptModal from '../../views/ListView/components/ViewReceiptModal'
|
||||
|
||||
function ViewTransactionModal({
|
||||
data: { transaction },
|
||||
onClose
|
||||
@@ -11,19 +22,221 @@ function ViewTransactionModal({
|
||||
}
|
||||
onClose: () => void
|
||||
}) {
|
||||
//TODO
|
||||
const { t } = useTranslation('apps.wallet')
|
||||
const open = useModalStore(state => state.open)
|
||||
const { assetsQuery, categoriesQuery, ledgersQuery } = useWalletData()
|
||||
const { componentBgLighter } = useComponentBg()
|
||||
const asset = assetsQuery.data?.find(asset => asset.id === transaction.asset)
|
||||
const category = categoriesQuery.data?.find(
|
||||
category => category.id === transaction.category
|
||||
)
|
||||
const ledger = ledgersQuery.data?.find(
|
||||
ledger => ledger.id === transaction.ledger
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="min-w-[30vw] space-y-4">
|
||||
<ModalHeader
|
||||
icon="tabler:eye"
|
||||
title="View Transaction"
|
||||
namespace="apps.wallet"
|
||||
title="transactions.view"
|
||||
onClose={onClose}
|
||||
/>
|
||||
<pre>
|
||||
<code className="break-words whitespace-pre-wrap">
|
||||
{JSON.stringify(transaction, null, 2)}
|
||||
</code>
|
||||
</pre>
|
||||
<div className="flex-center flex flex-col">
|
||||
{category && (
|
||||
<div
|
||||
className="shadow-custom mb-6 w-min rounded-lg p-4"
|
||||
style={{
|
||||
backgroundColor: category.color + (category.color ? '50' : ''),
|
||||
color: category.color
|
||||
}}
|
||||
>
|
||||
<Icon className="size-8" icon={category.icon ?? ''} />
|
||||
</div>
|
||||
)}
|
||||
{transaction.type === 'transfer' && (
|
||||
<div className="mb-6 w-min rounded-lg bg-blue-500/20 p-4">
|
||||
<Icon
|
||||
className="size-8 text-blue-500"
|
||||
icon="tabler:arrows-exchange"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-2 text-center text-4xl font-medium">
|
||||
<span className="text-bg-500 mr-2">
|
||||
{transaction.side === 'debit' ? '+' : '-'}
|
||||
</span>
|
||||
RM{' '}
|
||||
{Intl.NumberFormat('en-MY', {
|
||||
maximumFractionDigits: 2,
|
||||
minimumFractionDigits: 2
|
||||
}).format(transaction.amount)}
|
||||
</div>
|
||||
<p className="text-center text-lg">{transaction.particulars}</p>
|
||||
<p className="text-bg-500 mt-2 text-center">
|
||||
{dayjs(transaction.date).format('dddd, D MMM YYYY')}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<div
|
||||
className={clsx(
|
||||
'flex-between mt-6 rounded-lg p-4',
|
||||
componentBgLighter
|
||||
)}
|
||||
>
|
||||
<div className="text-bg-500 flex items-center gap-3">
|
||||
<Icon className="size-6" icon="tabler:exchange" />
|
||||
<h3 className="text-lg font-medium">
|
||||
{t('inputs.transactionType')}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="flex items-center gap-1">
|
||||
<Icon
|
||||
className={clsx('size-5', {
|
||||
'text-green-500': transaction.type === 'income',
|
||||
'text-red-500': transaction.type === 'expenses',
|
||||
'text-blue-500': transaction.type === 'transfer'
|
||||
})}
|
||||
icon={
|
||||
{
|
||||
income: 'tabler:login-2',
|
||||
expenses: 'tabler:logout',
|
||||
transfer: 'tabler:arrows-exchange'
|
||||
}[transaction.type]
|
||||
}
|
||||
/>
|
||||
{transaction.type.charAt(0).toUpperCase() +
|
||||
transaction.type.slice(1)}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className={clsx('flex-between rounded-lg p-4', componentBgLighter)}
|
||||
>
|
||||
<div className="text-bg-500 flex items-center gap-3">
|
||||
<Icon className="size-6" icon="tabler:calendar" />
|
||||
<h3 className="text-lg font-medium">{t('inputs.date')}</h3>
|
||||
</div>
|
||||
<p className="text-center">
|
||||
{dayjs(transaction.date).format('dddd, D MMM YYYY')}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
'flex-between mt-1 rounded-lg p-4',
|
||||
componentBgLighter
|
||||
)}
|
||||
>
|
||||
<div className="text-bg-500 flex items-center gap-3">
|
||||
<Icon className="size-6" icon="tabler:category" />
|
||||
<h3 className="text-lg font-medium">{t('inputs.category')}</h3>
|
||||
</div>
|
||||
<p className="flex items-center gap-1">
|
||||
<Icon
|
||||
className="size-6"
|
||||
icon={category!.icon}
|
||||
style={{
|
||||
color: category!.color
|
||||
}}
|
||||
/>
|
||||
{category!.name}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
'flex-between mt-1 rounded-lg p-4',
|
||||
componentBgLighter
|
||||
)}
|
||||
>
|
||||
<div className="text-bg-500 flex items-center gap-3">
|
||||
<Icon className="size-6" icon="tabler:wallet" />
|
||||
<h3 className="text-lg font-medium">{t('inputs.asset')}</h3>
|
||||
</div>
|
||||
<p className="flex items-center gap-1">
|
||||
<Icon className="size-6" icon={asset!.icon} />
|
||||
{asset!.name}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
'flex-between mt-1 rounded-lg p-4',
|
||||
componentBgLighter
|
||||
)}
|
||||
>
|
||||
<div className="text-bg-500 flex items-center gap-3">
|
||||
<Icon className="size-6" icon="tabler:book" />
|
||||
<h3 className="text-lg font-medium">{t('inputs.ledger')}</h3>
|
||||
</div>
|
||||
{ledger ? (
|
||||
<p className="flex items-center gap-1">
|
||||
<Icon
|
||||
className="size-6"
|
||||
icon={ledger.icon}
|
||||
style={{
|
||||
color: ledger.color
|
||||
}}
|
||||
/>
|
||||
{ledger.name}
|
||||
</p>
|
||||
) : (
|
||||
<span className="text-bg-500">No Ledger</span>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={clsx('mt-1 space-y-4 rounded-lg p-4', componentBgLighter)}
|
||||
>
|
||||
<div className="text-bg-500 flex items-center gap-3">
|
||||
<Icon className="size-6" icon="tabler:receipt" />
|
||||
<h3 className="text-lg font-medium">{t('inputs.receipt')}</h3>
|
||||
</div>
|
||||
{transaction.receipt ? (
|
||||
<Button
|
||||
className="w-full"
|
||||
icon="tabler:eye"
|
||||
namespace="apps.wallet"
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
open(ViewReceiptModal, {
|
||||
src: `${import.meta.env.VITE_API_HOST}/media/${transaction.collectionId}/${transaction.id}/${transaction.receipt}`
|
||||
})
|
||||
}}
|
||||
>
|
||||
View Receipt
|
||||
</Button>
|
||||
) : (
|
||||
<p className="text-bg-500 mb-2 text-center">No Receipt</p>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={clsx('mt-1 space-y-4 rounded-lg p-4', componentBgLighter)}
|
||||
>
|
||||
<div className="text-bg-500 flex items-center gap-3">
|
||||
<Icon className="size-6" icon="tabler:map-pin" />
|
||||
<h3 className="text-lg font-medium">{t('inputs.location')}</h3>
|
||||
</div>
|
||||
{transaction.location_name ? (
|
||||
<APIProvider apiKey={import.meta.env.VITE_GOOGLE_MAPS_API_KEY}>
|
||||
<Map
|
||||
className="h-96 overflow-hidden rounded-md"
|
||||
defaultCenter={{
|
||||
lat: transaction.location_coords?.lat || 0,
|
||||
lng: transaction.location_coords?.lon || 0
|
||||
}}
|
||||
defaultZoom={15}
|
||||
mapId="LocationMap"
|
||||
>
|
||||
<AdvancedMarker
|
||||
position={{
|
||||
lat: transaction.location_coords?.lat || 0,
|
||||
lng: transaction.location_coords?.lon || 0
|
||||
}}
|
||||
/>
|
||||
</Map>
|
||||
</APIProvider>
|
||||
) : (
|
||||
<p className="text-bg-500 mb-2 text-center">No Location</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useQueryClient } from '@tanstack/react-query'
|
||||
import clsx from 'clsx'
|
||||
import dayjs from 'dayjs'
|
||||
import { useCallback } from 'react'
|
||||
import { Tooltip } from 'react-tooltip'
|
||||
|
||||
import { DeleteConfirmationModal, HamburgerMenu, MenuItem } from '@lifeforge/ui'
|
||||
import { useModalStore } from '@lifeforge/ui'
|
||||
@@ -108,10 +107,10 @@ function TransactionListItem({
|
||||
<div className="flex w-full min-w-0 items-center gap-2">
|
||||
<div className="min-w-0 truncate text-lg font-medium">
|
||||
{transaction.particulars}{' '}
|
||||
{transaction.location !== '' && (
|
||||
{transaction.location_name !== '' && (
|
||||
<>
|
||||
<span className="text-bg-500">@</span>{' '}
|
||||
{`${transaction.location.split(',')[0]}`}
|
||||
{transaction.location_name}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -120,25 +119,6 @@ function TransactionListItem({
|
||||
<Icon className="text-bg-500 size-5" icon="tabler:file-text" />
|
||||
</button>
|
||||
)}
|
||||
{transaction.location !== '' && (
|
||||
<>
|
||||
<span data-tooltip-id={`tooltip-location-${transaction.id}`}>
|
||||
<Icon className="text-bg-500 size-5" icon="tabler:map-pin" />
|
||||
</span>
|
||||
<Tooltip
|
||||
className="bg-bg-50 text-bg-800 shadow-custom dark:bg-bg-800 dark:text-bg-50 z-9999 rounded-md! p-4! text-base!"
|
||||
classNameArrow="size-6!"
|
||||
id={`tooltip-location-${transaction.id}`}
|
||||
opacity={1}
|
||||
place="top-start"
|
||||
positionStrategy="fixed"
|
||||
>
|
||||
<div className="relative z-10 max-w-sm">
|
||||
{transaction.location}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-bg-500 flex items-center gap-2 text-sm font-medium">
|
||||
<span className="block sm:hidden">
|
||||
|
||||
Reference in New Issue
Block a user