Ajout de Promotion et de Commande fonctionnel
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react'
|
||||
|
||||
const STORAGE_KEY = 'librairie-promotions'
|
||||
|
||||
function loadPromotions() {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY)
|
||||
if (raw === null) return []
|
||||
const parsed = JSON.parse(raw)
|
||||
return Array.isArray(parsed) ? parsed : []
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
function savePromotions(promotions) {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(promotions))
|
||||
}
|
||||
|
||||
function normalizeCode(code) {
|
||||
return String(code || '')
|
||||
.trim()
|
||||
.toUpperCase()
|
||||
.replace(/\s+/g, '')
|
||||
}
|
||||
|
||||
const PromotionsContext = createContext(null)
|
||||
|
||||
export function PromotionsProvider({ children }) {
|
||||
const [promotions, setPromotions] = useState(loadPromotions)
|
||||
|
||||
useEffect(() => {
|
||||
savePromotions(promotions)
|
||||
}, [promotions])
|
||||
|
||||
const createPromotion = useCallback((promo) => {
|
||||
const code = normalizeCode(promo.code)
|
||||
const value = Number(promo.value)
|
||||
if (!code) throw new Error('Code promo invalide')
|
||||
if (!Number.isFinite(value) || value <= 0) {
|
||||
throw new Error('Valeur de promo invalide')
|
||||
}
|
||||
|
||||
setPromotions((prev) => {
|
||||
if (prev.some((p) => p.code === code)) {
|
||||
throw new Error('Ce code promo existe déjà')
|
||||
}
|
||||
return [
|
||||
...prev,
|
||||
{
|
||||
id: crypto.randomUUID(),
|
||||
code,
|
||||
type: 'percent',
|
||||
value,
|
||||
active: true,
|
||||
createdAt: new Date().toISOString(),
|
||||
},
|
||||
]
|
||||
})
|
||||
}, [])
|
||||
|
||||
const setPromotionActive = useCallback((code, active) => {
|
||||
const normalized = normalizeCode(code)
|
||||
setPromotions((prev) =>
|
||||
prev.map((p) => (p.code === normalized ? { ...p, active } : p)),
|
||||
)
|
||||
}, [])
|
||||
|
||||
const removePromotion = useCallback((code) => {
|
||||
const normalized = normalizeCode(code)
|
||||
setPromotions((prev) => prev.filter((p) => p.code !== normalized))
|
||||
}, [])
|
||||
|
||||
const getActivePromotionByCode = useCallback(
|
||||
(code) => {
|
||||
const normalized = normalizeCode(code)
|
||||
return promotions.find((p) => p.code === normalized && p.active) || null
|
||||
},
|
||||
[promotions],
|
||||
)
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
promotions,
|
||||
createPromotion,
|
||||
removePromotion,
|
||||
setPromotionActive,
|
||||
getActivePromotionByCode,
|
||||
normalizeCode,
|
||||
}),
|
||||
[
|
||||
promotions,
|
||||
createPromotion,
|
||||
removePromotion,
|
||||
setPromotionActive,
|
||||
getActivePromotionByCode,
|
||||
],
|
||||
)
|
||||
|
||||
return (
|
||||
<PromotionsContext.Provider value={value}>
|
||||
{children}
|
||||
</PromotionsContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export function usePromotions() {
|
||||
const ctx = useContext(PromotionsContext)
|
||||
if (!ctx) {
|
||||
throw new Error('usePromotions doit être utilisé dans un PromotionsProvider')
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user