base commit
This commit is contained in:
@@ -1,26 +0,0 @@
|
||||
const KEY = 'craftshop_admin_token'
|
||||
const TOKEN_EVENT = 'craftshop_admin_token_change'
|
||||
|
||||
export function getAdminToken(): string | null {
|
||||
return sessionStorage.getItem(KEY)
|
||||
}
|
||||
|
||||
function notifyTokenListeners(): void {
|
||||
window.dispatchEvent(new Event(TOKEN_EVENT))
|
||||
}
|
||||
|
||||
/** Подписаться на смену токена (в т. ч. после setAdminToken). */
|
||||
export function subscribeAdminTokenChange(cb: () => void): () => void {
|
||||
window.addEventListener(TOKEN_EVENT, cb)
|
||||
return () => window.removeEventListener(TOKEN_EVENT, cb)
|
||||
}
|
||||
|
||||
export function setAdminToken(token: string): void {
|
||||
sessionStorage.setItem(KEY, token)
|
||||
notifyTokenListeners()
|
||||
}
|
||||
|
||||
export function clearAdminToken(): void {
|
||||
sessionStorage.removeItem(KEY)
|
||||
notifyTokenListeners()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export function getErrorMessage(error: unknown, fallback = 'Произошла ошибка'): string {
|
||||
if (error instanceof Error && error.message) return error.message
|
||||
return fallback
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
type OrderLike = {
|
||||
status: string
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export function groupOrdersByStatus<T extends OrderLike>(items: T[], statuses: readonly string[]) {
|
||||
const byStatus = new Map<string, T[]>()
|
||||
for (const status of statuses) byStatus.set(status, [])
|
||||
|
||||
for (const item of items) {
|
||||
const list = byStatus.get(item.status) ?? []
|
||||
list.push(item)
|
||||
byStatus.set(item.status, list)
|
||||
}
|
||||
|
||||
return statuses
|
||||
.map((status) => ({
|
||||
status,
|
||||
items: (byStatus.get(status) ?? []).sort(
|
||||
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
|
||||
),
|
||||
}))
|
||||
.filter((group) => group.items.length > 0)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { QueryClient, QueryKey } from '@tanstack/react-query'
|
||||
|
||||
export async function invalidateQueryKeys(queryClient: QueryClient, keys: QueryKey[]): Promise<void> {
|
||||
await Promise.all(keys.map((queryKey) => queryClient.invalidateQueries({ queryKey })))
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { useCallback, useState } from 'react'
|
||||
|
||||
export function useEditDialogState<T>() {
|
||||
const [dialogOpen, setDialogOpen] = useState(false)
|
||||
const [editing, setEditing] = useState<T | null>(null)
|
||||
|
||||
const openCreateDialog = useCallback(() => {
|
||||
setEditing(null)
|
||||
setDialogOpen(true)
|
||||
}, [])
|
||||
|
||||
const openEditDialog = useCallback((item: T) => {
|
||||
setEditing(item)
|
||||
setDialogOpen(true)
|
||||
}, [])
|
||||
|
||||
const closeDialog = useCallback(() => {
|
||||
setDialogOpen(false)
|
||||
}, [])
|
||||
|
||||
return {
|
||||
dialogOpen,
|
||||
editing,
|
||||
openCreateDialog,
|
||||
openEditDialog,
|
||||
closeDialog,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user