convert trade form inputs to tailwind and continue theming
This commit is contained in:
parent
932b52f649
commit
6605cbdd48
|
@ -70,6 +70,7 @@ const AccountSelect = ({
|
|||
</Listbox.Button>
|
||||
<Transition
|
||||
show={open}
|
||||
appear={true}
|
||||
enter="transition duration-100 ease-out"
|
||||
enterFrom="transform scale-95 opacity-0"
|
||||
enterTo="transform scale-100 opacity-100"
|
||||
|
|
|
@ -13,17 +13,39 @@ const Input = ({
|
|||
onChange,
|
||||
className,
|
||||
disabled,
|
||||
prefix,
|
||||
suffix,
|
||||
...props
|
||||
}: InputProps) => {
|
||||
return (
|
||||
<input
|
||||
type={type}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className={`bg-th-bkg-1 ${className}`}
|
||||
disabled={disabled}
|
||||
{...props}
|
||||
/>
|
||||
<div
|
||||
className={`flex items-center rounded ${
|
||||
disabled ? 'bg-th-bkg-3' : 'bg-th-bkg-1'
|
||||
} ${className}`}
|
||||
>
|
||||
{prefix ? (
|
||||
<div className="border-r border-th-fgd-4 bg-th-bkg-2 p-2 rounded rounded-r-none">
|
||||
{prefix}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="flex h-full">
|
||||
<input
|
||||
type={type}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className={`bg-transparent w-full font-light focus:outline-none ${
|
||||
disabled && 'opacity-20 cursor-not-allowed'
|
||||
} ${type === 'number' ? 'text-right' : ''}`}
|
||||
disabled={disabled}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
{suffix ? (
|
||||
<span className="text-xs px-2 bg-transparent text-th-fgd-4">
|
||||
{suffix}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,11 @@ const MarketSelect = () => {
|
|||
>
|
||||
{Object.entries(spotMarkets).map(([name, address]) => (
|
||||
<div
|
||||
className={`cursor-pointer
|
||||
className={`px-3 py-1 cursor-pointer text-sm font-normal
|
||||
${
|
||||
selectedMarket.name === name
|
||||
? `px-3 py-1 text-th-primary text-xs font-normal`
|
||||
: `px-3 py-1 text-th-fgd-3 hover:text-th-fgd-1 text-xs font-normal`
|
||||
? `text-th-primary`
|
||||
: `text-th-fgd-3 hover:text-th-fgd-1`
|
||||
}
|
||||
`}
|
||||
onClick={() => handleChange(name)}
|
||||
|
|
|
@ -9,7 +9,6 @@ import useMangoStore from '../stores/useMangoStore'
|
|||
const NotificationList = () => {
|
||||
const setMangoStore = useMangoStore((s) => s.set)
|
||||
const notifications = useMangoStore((s) => s.notifications)
|
||||
console.log('notifications', notifications)
|
||||
|
||||
useEffect(() => {
|
||||
if (notifications.length > 0) {
|
||||
|
@ -70,7 +69,13 @@ const Notification = ({ type, message, description, txid }) => {
|
|||
<p className={`text-lg font-medium text-gray-900`}>{message}</p>
|
||||
<p className={`mt-0.5 text-base text-gray-500`}>{description}</p>
|
||||
{txid ? (
|
||||
<p className={`mt-0.5 text-sm text-gray-500`}>{txid}</p>
|
||||
<a
|
||||
href={'https://explorer.solana.com/tx/' + txid}
|
||||
className="text-th-blue-400"
|
||||
>
|
||||
View transaction {txid.slice(0, 8)}...
|
||||
{txid.slice(txid.length - 8)}
|
||||
</a>
|
||||
) : null}
|
||||
</div>
|
||||
<div className={`ml-4 flex-shrink-0 flex`}>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useState, useEffect, useRef } from 'react'
|
||||
import { Input, Radio, Switch, Select } from 'antd'
|
||||
import { Switch } from 'antd'
|
||||
import useMarket from '../hooks/useMarket'
|
||||
import useIpAddress from '../hooks/useIpAddress'
|
||||
import useConnection from '../hooks/useConnection'
|
||||
|
@ -12,7 +12,8 @@ import FloatingElement from './FloatingElement'
|
|||
import { roundToDecimal } from '../utils/index'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import Button from './Button'
|
||||
// import TradeType from './TradeType'
|
||||
import TradeType from './TradeType'
|
||||
import NewInput from './Input'
|
||||
|
||||
export default function TradeForm({
|
||||
setChangeOrderRef,
|
||||
|
@ -21,12 +22,17 @@ export default function TradeForm({
|
|||
ref: ({ size, price }: { size?: number; price?: number }) => void
|
||||
) => void
|
||||
}) {
|
||||
const [side, setSide] = useState<'buy' | 'sell'>('buy')
|
||||
const { baseCurrency, quoteCurrency, market, marketAddress } = useMarket()
|
||||
const set = useMangoStore((s) => s.set)
|
||||
const { connected } = useMangoStore((s) => s.wallet)
|
||||
|
||||
const { connection, cluster } = useConnection()
|
||||
const tradeForm = useMangoStore((s) => s.tradeForm)
|
||||
const { side, baseSize, quoteSize, price, tradeType } = useMangoStore(
|
||||
(s) => s.tradeForm
|
||||
)
|
||||
const { ipAllowed } = useIpAddress()
|
||||
const [postOnly, setPostOnly] = useState(false)
|
||||
const [ioc, setIoc] = useState(false)
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
|
||||
const orderBookRef = useRef(useMangoStore.getState().market.orderBook)
|
||||
const orderbook = orderBookRef.current[0]
|
||||
|
@ -39,6 +45,31 @@ export default function TradeForm({
|
|||
[]
|
||||
)
|
||||
|
||||
const setSide = (side) =>
|
||||
set((s) => {
|
||||
s.tradeForm.side = side
|
||||
})
|
||||
|
||||
const setBaseSize = (baseSize) =>
|
||||
set((s) => {
|
||||
s.tradeForm.baseSize = parseFloat(baseSize)
|
||||
})
|
||||
|
||||
const setQuoteSize = (quoteSize) =>
|
||||
set((s) => {
|
||||
s.tradeForm.quoteSize = parseFloat(quoteSize)
|
||||
})
|
||||
|
||||
const setPrice = (price) =>
|
||||
set((s) => {
|
||||
s.tradeForm.price = parseFloat(price)
|
||||
})
|
||||
|
||||
const setTradeType = (type) =>
|
||||
set((s) => {
|
||||
s.tradeForm.tradeType = type
|
||||
})
|
||||
|
||||
const markPriceRef = useRef(useMangoStore.getState().market.markPrice)
|
||||
const markPrice = markPriceRef.current
|
||||
useEffect(
|
||||
|
@ -50,16 +81,6 @@ export default function TradeForm({
|
|||
[]
|
||||
)
|
||||
|
||||
const { ipAllowed } = useIpAddress()
|
||||
|
||||
const [postOnly, setPostOnly] = useState(false)
|
||||
const [ioc, setIoc] = useState(false)
|
||||
const [baseSize, setBaseSize] = useState<number | undefined>(undefined)
|
||||
const [quoteSize, setQuoteSize] = useState<number | undefined>(undefined)
|
||||
const [price, setPrice] = useState<number | undefined>(undefined)
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const [tradeType, setTradeType] = useState('Limit')
|
||||
|
||||
const sizeDecimalCount =
|
||||
market?.minOrderSize && getDecimalCount(market.minOrderSize)
|
||||
const priceDecimalCount = market?.tickSize && getDecimalCount(market.tickSize)
|
||||
|
@ -69,25 +90,6 @@ export default function TradeForm({
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [setChangeOrderRef])
|
||||
|
||||
useEffect(() => {
|
||||
if (!price && markPrice && tradeType !== 'Market') {
|
||||
setPrice(markPrice)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [price, baseSize, quoteSize])
|
||||
|
||||
// Set the price from the balance comp
|
||||
useEffect(() => {
|
||||
if (tradeForm.currency) {
|
||||
if (tradeForm.currency === baseCurrency) {
|
||||
// onSetBaseSize(size.size);
|
||||
} else {
|
||||
// onSetQuoteSize(size.size);
|
||||
}
|
||||
}
|
||||
}, [tradeForm])
|
||||
|
||||
const onSetBaseSize = (baseSize: number | undefined) => {
|
||||
setBaseSize(baseSize)
|
||||
if (!baseSize) {
|
||||
|
@ -175,8 +177,8 @@ export default function TradeForm({
|
|||
if (tradeType === 'Market') {
|
||||
calculatedPrice =
|
||||
side === 'buy'
|
||||
? calculateMarketPrice(orderbook.asks, tradeForm.size, side)
|
||||
: calculateMarketPrice(orderbook.bids, tradeForm.size, side)
|
||||
? calculateMarketPrice(orderbook.asks, baseSize, side)
|
||||
: calculateMarketPrice(orderbook.bids, baseSize, side)
|
||||
}
|
||||
|
||||
await placeAndSettle(
|
||||
|
@ -210,7 +212,7 @@ export default function TradeForm({
|
|||
setTradeType(tradeType)
|
||||
if (tradeType === 'Market') {
|
||||
setIoc(true)
|
||||
setPrice(undefined)
|
||||
setPrice('')
|
||||
} else {
|
||||
const limitPrice =
|
||||
side === 'buy' ? orderbook.asks[0][0] : orderbook.bids[0][0]
|
||||
|
@ -222,94 +224,74 @@ export default function TradeForm({
|
|||
return (
|
||||
<FloatingElement>
|
||||
<div>
|
||||
<Radio.Group
|
||||
onChange={(e) => setSide(e.target.value)}
|
||||
value={side}
|
||||
buttonStyle="solid"
|
||||
style={{
|
||||
marginBottom: 8,
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Radio.Button
|
||||
value="buy"
|
||||
style={{
|
||||
width: '50%',
|
||||
textAlign: 'center',
|
||||
color: side === 'buy' ? '#141026' : '',
|
||||
background: side === 'buy' ? '#AFD803' : '',
|
||||
borderColor: side === 'buy' ? '#AFD803' : '',
|
||||
}}
|
||||
<div className={`flex text-base text-th-fgd-4`}>
|
||||
<button
|
||||
onClick={() => setSide('buy')}
|
||||
className={`flex-1 outline-none focus:outline-none`}
|
||||
>
|
||||
BUY
|
||||
</Radio.Button>
|
||||
<Radio.Button
|
||||
className="sell-button"
|
||||
value="sell"
|
||||
style={{
|
||||
width: '50%',
|
||||
textAlign: 'center',
|
||||
background: side === 'sell' ? '#E54033' : '',
|
||||
borderColor: side === 'sell' ? '#E54033' : '',
|
||||
}}
|
||||
<div
|
||||
className={`hover:text-th-primary pb-1
|
||||
${
|
||||
side === 'buy' &&
|
||||
`text-th-green hover:text-th-green border-b-2 border-th-green`
|
||||
}`}
|
||||
>
|
||||
Buy
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setSide('sell')}
|
||||
className={`flex-1 outline-none focus:outline-none`}
|
||||
>
|
||||
SELL
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
<Input.Group compact style={{ paddingBottom: 8 }}>
|
||||
<Input
|
||||
style={{
|
||||
width: 'calc(50% + 30px)',
|
||||
textAlign: 'right',
|
||||
paddingBottom: 8,
|
||||
}}
|
||||
addonBefore={<div style={{ width: '30px' }}>Price</div>}
|
||||
suffix={
|
||||
<span style={{ fontSize: 10, opacity: 0.5 }}>
|
||||
{quoteCurrency}
|
||||
</span>
|
||||
}
|
||||
value={price}
|
||||
<div
|
||||
className={`hover:text-th-primary pb-1
|
||||
${
|
||||
side === 'sell' &&
|
||||
`text-th-red hover:text-th-red border-b-2 border-th-red`
|
||||
}
|
||||
`}
|
||||
>
|
||||
Sell
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<NewInput.Group className="mt-4">
|
||||
<NewInput
|
||||
type="number"
|
||||
step={market?.tickSize || 1}
|
||||
onChange={(e) => setPrice(parseFloat(e.target.value))}
|
||||
value={price}
|
||||
disabled={tradeType === 'Market'}
|
||||
prefix={'Price'}
|
||||
suffix={quoteCurrency}
|
||||
className="w-3/5"
|
||||
/>
|
||||
{/* <TradeType onChange={handleTradeTypeChange} value={tradeType} /> */}
|
||||
<Select
|
||||
style={{ width: 'calc(50% - 30px)' }}
|
||||
<TradeType
|
||||
onChange={handleTradeTypeChange}
|
||||
value={tradeType}
|
||||
>
|
||||
<Select.Option value="Limit">Limit</Select.Option>
|
||||
<Select.Option value="Market">Market</Select.Option>
|
||||
</Select>
|
||||
</Input.Group>
|
||||
<Input.Group compact style={{ paddingBottom: 8 }}>
|
||||
<Input
|
||||
style={{ width: 'calc(50% + 30px)', textAlign: 'right' }}
|
||||
addonBefore={<div style={{ width: '30px' }}>Size</div>}
|
||||
suffix={
|
||||
<span style={{ fontSize: 10, opacity: 0.5 }}>{baseCurrency}</span>
|
||||
}
|
||||
value={baseSize}
|
||||
className="w-2/5"
|
||||
/>
|
||||
</NewInput.Group>
|
||||
|
||||
<NewInput.Group className="mt-4">
|
||||
<NewInput
|
||||
type="number"
|
||||
step={market?.minOrderSize || 1}
|
||||
onChange={(e) => onSetBaseSize(parseFloat(e.target.value))}
|
||||
value={baseSize}
|
||||
className="text-right flex-grow w-3/5"
|
||||
prefix={'Size'}
|
||||
suffix={baseCurrency}
|
||||
/>
|
||||
<Input
|
||||
style={{ width: 'calc(50% - 30px)', textAlign: 'right' }}
|
||||
suffix={
|
||||
<span style={{ fontSize: 10, opacity: 0.5 }}>
|
||||
{quoteCurrency}
|
||||
</span>
|
||||
}
|
||||
value={quoteSize}
|
||||
<NewInput
|
||||
type="number"
|
||||
step={market?.minOrderSize || 1}
|
||||
onChange={(e) => onSetQuoteSize(parseFloat(e.target.value))}
|
||||
value={quoteSize}
|
||||
className="text-right border-l border-th-fgd-4 rounded-l-none w-2/5"
|
||||
suffix={quoteCurrency}
|
||||
/>
|
||||
</Input.Group>
|
||||
</NewInput.Group>
|
||||
{tradeType !== 'Market' ? (
|
||||
<div style={{ paddingTop: 18 }}>
|
||||
{'POST '}
|
||||
|
@ -317,14 +299,9 @@ export default function TradeForm({
|
|||
checked={postOnly}
|
||||
onChange={postOnChange}
|
||||
style={{ marginRight: 40 }}
|
||||
disabled={tradeType === 'Market'}
|
||||
/>
|
||||
{'IOC '}
|
||||
<Switch
|
||||
checked={ioc}
|
||||
onChange={iocOnChange}
|
||||
disabled={tradeType === 'Market'}
|
||||
/>
|
||||
<Switch checked={ioc} onChange={iocOnChange} />
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
@ -340,7 +317,7 @@ export default function TradeForm({
|
|||
}
|
||||
grow={true}
|
||||
onClick={onSubmit}
|
||||
className={`text-lg font-light bg-mango-green text-mango-dark hover:bg-mango-yellow flex-grow`}
|
||||
className={`rounded text-lg font-light bg-th-green text-th-bkg-1 hover:bg-th-primary flex-grow`}
|
||||
>
|
||||
{connected ? `Buy ${baseCurrency}` : 'CONNECT WALLET TO TRADE'}
|
||||
</Button>
|
||||
|
@ -354,7 +331,7 @@ export default function TradeForm({
|
|||
}
|
||||
grow={true}
|
||||
onClick={onSubmit}
|
||||
className={`text-lg font-light bg-mango-red text-white hover:bg-mango-yellow flex-grow`}
|
||||
className={`rounded text-lg font-light bg-th-red text-white hover:bg-th-primary flex-grow`}
|
||||
>
|
||||
{connected ? `Sell ${baseCurrency}` : 'CONNECT WALLET TO TRADE'}
|
||||
</Button>
|
||||
|
|
|
@ -27,8 +27,8 @@ const layouts = {
|
|||
],
|
||||
lg: [
|
||||
{ i: 'tvChart', x: 0, y: 0, w: 2, h: 24 },
|
||||
{ i: 'balanceInfo', x: 2, y: 0, w: 1, h: 12 },
|
||||
{ i: 'marginStats', x: 2, y: 1, w: 1, h: 12 },
|
||||
{ i: 'balanceInfo', x: 2, y: 0, w: 1, h: 13 },
|
||||
{ i: 'marginStats', x: 2, y: 1, w: 1, h: 11 },
|
||||
{ i: 'orderbook', x: 0, y: 2, w: 1, h: 17 },
|
||||
{ i: 'tradeForm', x: 1, y: 2, w: 1, h: 17 },
|
||||
{ i: 'marketTrades', x: 2, y: 2, w: 1, h: 17 },
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
import { Listbox, Transition } from '@headlessui/react'
|
||||
import { Listbox } from '@headlessui/react'
|
||||
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/solid'
|
||||
|
||||
const TradeType = ({ value, onChange }) => {
|
||||
const TRADE_TYPES = ['Limit', 'Market']
|
||||
|
||||
const TradeType = ({ value, onChange, className = '' }) => {
|
||||
return (
|
||||
<div className={`ml-4 relative inline-block -mb-1`}>
|
||||
<div className={`relative ${className}`}>
|
||||
<Listbox value={value} onChange={onChange}>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Listbox.Button
|
||||
className={`border border-mango-dark-lighter focus:outline-none focus:ring-1 focus:ring-mango-yellow p-2 w-56`}
|
||||
className={`h-full w-full border-l border-th-fgd-4 focus:outline-none focus:ring-1 focus:ring-th-primary`}
|
||||
>
|
||||
<div
|
||||
className={`flex items-center text-lg justify-between font-light`}
|
||||
className={`flex items-center justify-between space-x-4 font-light pl-2`}
|
||||
>
|
||||
{value}
|
||||
<span>{value}</span>
|
||||
{open ? (
|
||||
<ChevronUpIcon className={`h-5 w-5 mr-1`} />
|
||||
) : (
|
||||
|
@ -21,35 +23,26 @@ const TradeType = ({ value, onChange }) => {
|
|||
)}
|
||||
</div>
|
||||
</Listbox.Button>
|
||||
<Transition
|
||||
show={open}
|
||||
enter="transition duration-100 ease-out"
|
||||
enterFrom="transform scale-95 opacity-0"
|
||||
enterTo="transform scale-100 opacity-100"
|
||||
leave="transition duration-75 ease-out"
|
||||
leaveFrom="transform scale-100 opacity-100"
|
||||
leaveTo="transform scale-95 opacity-0"
|
||||
>
|
||||
{open ? (
|
||||
<Listbox.Options
|
||||
static
|
||||
className={`z-20 p-1 absolute left-0 w-56 mt-1 bg-mango-dark-light origin-top-left divide-y divide-mango-dark-lighter shadow-lg outline-none`}
|
||||
className={`z-20 w-full p-1 absolute left-0 mt-1 bg-th-bkg-3 origin-top-left divide-y divide-th-fgd-4 shadow-lg outline-none`}
|
||||
>
|
||||
<div className={`opacity-50 p-2`}>Markets</div>
|
||||
{['Limit', 'Market'].map((type) => (
|
||||
<Listbox.Option key={type} value={name}>
|
||||
{TRADE_TYPES.map((type) => (
|
||||
<Listbox.Option key={type} value={type}>
|
||||
{({ selected }) => (
|
||||
<div
|
||||
className={`p-2 text-base hover:bg-mango-dark-lighter hover:cursor-pointer tracking-wider font-light ${
|
||||
selected && 'text-mango-yellow bg-mango-dark-lighter'
|
||||
className={`p-2 text-base hover:bg-th-fgd-4 hover:cursor-pointer tracking-wider font-light ${
|
||||
selected && `text-th-primary`
|
||||
}`}
|
||||
>
|
||||
{name}
|
||||
{type}
|
||||
</div>
|
||||
)}
|
||||
</Listbox.Option>
|
||||
))}
|
||||
</Listbox.Options>
|
||||
</Transition>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</Listbox>
|
||||
|
|
|
@ -5,13 +5,9 @@ import useSerumStore from '../stores/useSerumStore'
|
|||
import useOrderbook from './useOrderbook'
|
||||
import useConnection from './useConnection'
|
||||
|
||||
// const _VERY_SLOW_REFRESH_INTERVAL = 5000 * 1000;
|
||||
|
||||
// For things that don't really change
|
||||
const _SLOW_REFRESH_INTERVAL = 5 * 1000
|
||||
|
||||
// For things that change frequently
|
||||
// const _FAST_REFRESH_INTERVAL = 1000;
|
||||
const _SLOW_REFRESH_INTERVAL = 5 * 1000
|
||||
// const _VERY_SLOW_REFRESH_INTERVAL = 5000 * 1000;
|
||||
|
||||
export function _useUnfilteredTrades(limit = 10000) {
|
||||
console.log('fetching unfiltered trades')
|
||||
|
|
|
@ -39,6 +39,8 @@ export default function useWallet() {
|
|||
useEffect(() => {
|
||||
if (!wallet) return
|
||||
wallet.on('connect', () => {
|
||||
console.log('connected')
|
||||
|
||||
setMangoStore((state) => {
|
||||
state.wallet.connected = true
|
||||
})
|
||||
|
|
|
@ -11,7 +11,7 @@ const Index = () => {
|
|||
<div className={`bg-th-bkg-1 text-th-fgd-1 transition-all`}>
|
||||
<TopBar />
|
||||
<MarketSelect />
|
||||
<div className={`min-h-screen p-1 sm:p-2 md:p-6 md:pt-4`}>
|
||||
<div className={`min-h-screen p-1 sm:px-2 sm:py-1 md:px-6 md:py-1`}>
|
||||
<TradePageGrid />
|
||||
</div>
|
||||
<Notifications />
|
||||
|
|
|
@ -76,9 +76,11 @@ interface MangoStore extends State {
|
|||
current: MarginAccount | null
|
||||
}
|
||||
tradeForm: {
|
||||
side: string
|
||||
currency: string
|
||||
size: number
|
||||
side: 'buy' | 'sell'
|
||||
price: number | ''
|
||||
baseSize: number | ''
|
||||
quoteSize: number | ''
|
||||
tradeType: 'Market' | 'Limit'
|
||||
}
|
||||
wallet: {
|
||||
connected: boolean
|
||||
|
@ -127,8 +129,10 @@ const useMangoStore = create<MangoStore>(
|
|||
},
|
||||
tradeForm: {
|
||||
side: 'buy',
|
||||
size: 0,
|
||||
currency: 'BTC',
|
||||
baseSize: '',
|
||||
quoteSize: '',
|
||||
tradeType: 'Limit',
|
||||
price: '',
|
||||
},
|
||||
wallet: {
|
||||
connected: false,
|
||||
|
|
|
@ -7,10 +7,13 @@ export function notify(newNotification: {
|
|||
txid?: string
|
||||
}) {
|
||||
const setMangoStore = useMangoStore.getState().set
|
||||
const notifications = useMangoStore.getState().notifications
|
||||
|
||||
setMangoStore((state) => {
|
||||
console.log('original', state.notifications)
|
||||
|
||||
state.notifications = [
|
||||
...state.notifications,
|
||||
...notifications,
|
||||
{ type: 'success', ...newNotification },
|
||||
]
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue