add zustard
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
import { applyDiscount, type Coupon } from './discount'
|
||||
import { calcInterest, type CreditCard } from './payment'
|
||||
import type { PaymentMethod } from '@repo/ui/routes/orders/data'
|
||||
import type { Enrollment } from '../_.$orgid.enrollments.add/data'
|
||||
import type { Item } from './bulk'
|
||||
|
||||
export type WizardState = {
|
||||
index: number
|
||||
kind: 'bulk' | 'assigned'
|
||||
items: Item[]
|
||||
enrollments: Enrollment[]
|
||||
coupon?: Coupon
|
||||
installments?: number
|
||||
payment_method?: PaymentMethod
|
||||
credit_card?: CreditCard
|
||||
}
|
||||
|
||||
type Summary = {
|
||||
subtotal: number
|
||||
discount: number
|
||||
interest_amount: number
|
||||
total: number
|
||||
}
|
||||
|
||||
export type WizardStore = WizardState & {
|
||||
setIndex: (index: number) => void
|
||||
setKind: (kind: 'bulk' | 'assigned') => void
|
||||
update: (data: Partial<WizardState>) => void
|
||||
reset: () => void
|
||||
summary: () => Summary
|
||||
}
|
||||
|
||||
const emptyWizard: WizardState = {
|
||||
index: 0,
|
||||
kind: 'bulk',
|
||||
items: [],
|
||||
enrollments: []
|
||||
}
|
||||
|
||||
export const useWizardStore = create<WizardStore>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
...emptyWizard,
|
||||
|
||||
setIndex: (index) => set({ index }),
|
||||
setKind: (kind) => set({ kind }),
|
||||
|
||||
summary: () => {
|
||||
const { items, coupon, credit_card, installments } = get()
|
||||
const subtotal = items.reduce(
|
||||
(acc, { course, quantity }) =>
|
||||
acc +
|
||||
(course?.unit_price || 0) *
|
||||
(Number.isFinite(quantity) && quantity > 0 ? quantity : 1),
|
||||
0
|
||||
)
|
||||
const discount = coupon
|
||||
? applyDiscount(subtotal, coupon.amount, coupon.type) * -1
|
||||
: 0
|
||||
|
||||
const total = subtotal > 0 ? subtotal + discount : 0
|
||||
const interest_amount =
|
||||
credit_card && typeof installments === 'number' && installments > 1
|
||||
? calcInterest(total, installments) - total
|
||||
: 0
|
||||
|
||||
return {
|
||||
subtotal,
|
||||
discount,
|
||||
interest_amount,
|
||||
total: total + interest_amount
|
||||
}
|
||||
},
|
||||
|
||||
update: (data) =>
|
||||
set((state) => {
|
||||
if (data.enrollments) {
|
||||
const items = Object.values(
|
||||
data.enrollments.reduce<Record<string, Item>>(
|
||||
(acc, { course }) => {
|
||||
const { id } = course
|
||||
|
||||
acc[id] ??= { course, quantity: 0 }
|
||||
acc[id].quantity++
|
||||
|
||||
return acc
|
||||
},
|
||||
{}
|
||||
)
|
||||
)
|
||||
|
||||
return {
|
||||
...state,
|
||||
...data,
|
||||
items
|
||||
}
|
||||
}
|
||||
|
||||
if (data.items) {
|
||||
const items = Object.values(
|
||||
data.items.reduce<Record<string, Item>>((acc, item) => {
|
||||
const id = item.course.id
|
||||
|
||||
if (!acc[id]) {
|
||||
acc[id] = { ...item }
|
||||
} else {
|
||||
acc[id].quantity += item.quantity
|
||||
}
|
||||
|
||||
return acc
|
||||
}, {})
|
||||
)
|
||||
|
||||
return {
|
||||
...state,
|
||||
...data,
|
||||
items,
|
||||
enrollments: []
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
...data
|
||||
}
|
||||
}),
|
||||
|
||||
reset: () => set({ ...emptyWizard })
|
||||
}),
|
||||
{
|
||||
name: 'wizard_cart'
|
||||
}
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user